Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

unicode: Support characters beyond the first unicode plane

We used 16-bit variables to store the 'character code' everywhere but
this won't let us represent anything beyond U+FFFF.

This patch changes those variables to a custom type that can be 32 or 16
bits depending on the build, and adjusts numerous internal APIs and
datastructures to match. This includes:

* utf8decode() and friends
* font manipulation, caching, rendering, and generation
* on-screen keyboard
* FAT filesystem (parsing and generating utf16 LFNs)
* WIN32 simulator platform code

Note that this patch doesn't _enable_ >16bit unicode support; a followup
patch will turn that on for appropriate targets.

Appears to work on:

* hosted linux, native, linux simulator in both 16/32-bit modes.

Needs testing on:

* windows and macos simulator (16bit+32bit)

Change-Id: Iba111b27d2433019b6bff937cf1ebd2c4353a0e8

+475 -329
+2 -2
apps/hosted/android/keyboard.c
··· 82 82 sleep(HZ/10); 83 83 } 84 84 85 - int kbd_input(char* text, int buflen, unsigned short *kbd) 85 + int kbd_input(char* text, int buflen, ucschar_t *kbd) 86 86 { 87 87 (void)kbd; 88 88 JNIEnv e = *env_ptr; ··· 107 107 e->DeleteLocalRef(env_ptr, str); 108 108 e->DeleteLocalRef(env_ptr, ok_text); 109 109 e->DeleteLocalRef(env_ptr, cancel_text); 110 - 110 + 111 111 return !accepted; /* return 0 on success */ 112 112 } 113 113
+1 -1
apps/keyboard.h
··· 23 23 24 24 /* '*kbd', same format as https://www.rockbox.org/wiki/LoadableKeyboardLayouts */ 25 25 26 - int kbd_input(char* buffer, int buflen, unsigned short *kbd); 26 + int kbd_input(char* buffer, int buflen, ucschar_t *kbd); 27 27 28 28 int load_kbd(unsigned char* filename); 29 29
+7 -7
apps/plugin.h
··· 176 176 * when this happens please take the opportunity to sort in 177 177 * any new functions "waiting" at the end of the list. 178 178 */ 179 - #define PLUGIN_API_VERSION 273 179 + #define PLUGIN_API_VERSION 274 180 180 181 181 /* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */ 182 182 ··· 296 296 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) 297 297 void (*button_queue_post)(long id, intptr_t data); 298 298 #endif 299 - unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation ); 300 - bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl); 301 - const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code ); 299 + ucschar_t *(*bidi_l2v)(const unsigned char *str, int orientation); 300 + bool (*is_diacritic)(const ucschar_t char_code, bool *is_rtl); 301 + const unsigned char *(*font_get_bits)(struct font *pf, ucschar_t char_code); 302 302 int (*font_load)(const char *path); 303 303 void (*font_unload)(int font_id); 304 304 struct font* (*font_get)(int font); 305 305 int (*font_getstringsize)(const unsigned char *str, int *w, int *h, 306 306 int fontnumber); 307 - int (*font_get_width)(struct font* pf, unsigned short char_code); 307 + int (*font_get_width)(struct font* pf, ucschar_t char_code); 308 308 void (*screen_clear_area)(struct screen * display, int xstart, int ystart, 309 309 int width, int height); 310 310 void (*gui_scrollbar_draw)(struct screen * screen, int x, int y, ··· 667 667 const unsigned char * const *units, 668 668 unsigned int unit_count, bool binary_scale); 669 669 /* unicode stuff */ 670 - const unsigned char* (*utf8decode)(const unsigned char *utf8, unsigned short *ucs); 670 + const unsigned char* (*utf8decode)(const unsigned char *utf8, ucschar_t *ucs); 671 671 unsigned char* (*iso_decode)(const unsigned char *iso, unsigned char *utf8, int cp, int count); 672 672 unsigned char* (*utf16LEdecode)(const unsigned char *utf16, unsigned char *utf8, int count); 673 673 unsigned char* (*utf16BEdecode)(const unsigned char *utf16, unsigned char *utf8, int count); ··· 923 923 int (*rand)(void); 924 924 void (*qsort)(void *base, size_t nmemb, size_t size, 925 925 int(*compar)(const void *, const void *)); 926 - int (*kbd_input)(char* buffer, int buflen, unsigned short *kbd); 926 + int (*kbd_input)(char* buffer, int buflen, ucschar_t *kbd); 927 927 struct tm* (*get_time)(void); 928 928 struct tm * (*gmtime_r)(const time_t *timep, struct tm *tm); 929 929 #if CONFIG_RTC
+3 -3
apps/plugins/announce_status.c
··· 70 70 * - \n does not create a key, but it also consumes one element 71 71 * - the final null terminator is equivalent to \n 72 72 * - since sizeof includes the null terminator we don't need +1 for that. */ 73 - static unsigned short kbd_buf[sizeof(keybd_layout)]; 73 + static ucschar_t kbd_buf[sizeof(keybd_layout)]; 74 74 75 75 /****************** prototypes ******************/ 76 76 void print_scroll(char* string); /* implements a scrolling screen */ ··· 164 164 gAnnounce.announce_on = 0; 165 165 gAnnounce.grouping = 0; 166 166 gAnnounce.wps_fmt[0] = '\0'; 167 - gAnnounce.show_prompt = true; 167 + gAnnounce.show_prompt = true; 168 168 } 169 169 170 170 static void config_reset_voice(void) ··· 250 250 struct gui_synclist *this_list) 251 251 { 252 252 (void)this_item; 253 - unsigned short* kbd_p; 253 + ucschar_t *kbd_p; 254 254 255 255 int selection = rb->gui_synclist_get_sel_pos(this_list); 256 256
+5 -5
apps/plugins/frotz/frotz.c
··· 128 128 case PLA_EXIT: 129 129 hot_key_quit(); 130 130 break; 131 - 131 + 132 132 case PLA_SELECT: 133 133 return; 134 134 } ··· 159 159 { 160 160 case PLA_EXIT: 161 161 return ZC_HKEY_QUIT; 162 - 162 + 163 163 case PLA_CANCEL: 164 164 menu_ret = menu(); 165 165 if (menu_ret != ZC_BAD) ··· 174 174 return ZC_BAD; 175 175 176 176 default: 177 - if (timeout != TIMEOUT_BLOCK && 177 + if (timeout != TIMEOUT_BLOCK && 178 178 !TIME_BEFORE(*rb->current_tick, timeout_at)) 179 179 return ZC_TIME_OUT; 180 180 } ··· 185 185 { 186 186 int r; 187 187 char inputbuf[5]; 188 - short key; 188 + ucschar_t key; 189 189 zchar zkey; 190 190 191 191 for(;;) ··· 214 214 char inputbuf[256]; 215 215 const char *in; 216 216 char *out; 217 - short key; 217 + ucschar_t key; 218 218 zchar zkey; 219 219 220 220 for(;;)
+4 -4
apps/plugins/keyremap.c
··· 206 206 { 207 207 #define KBD_LAYOUT "abcdefghijklmnop\nqrstuvwxyz |()[]\n1234567890 /._-+\n\n" \ 208 208 "\nABCDEFGHIJKLMNOP\nQRSTUVWXYZ |()[]\n1234567890 /._-+" 209 - unsigned short kbd[sizeof(KBD_LAYOUT) + 10]; 210 - unsigned short *kbd_p = kbd; 209 + ucschar_t kbd[sizeof(KBD_LAYOUT) + 10]; 210 + ucschar_t *kbd_p = kbd; 211 211 if (!kbd_create_layout(KBD_LAYOUT, kbd, sizeof(kbd))) 212 212 kbd_p = NULL; 213 213 ··· 1002 1002 { 1003 1003 bufleft = bufsz - (pctx - filenamebuf); 1004 1004 ctx = -1; 1005 - int ctx_x_flag_count = (LAST_CONTEXT_PLACEHOLDER 1005 + int ctx_x_flag_count = (LAST_CONTEXT_PLACEHOLDER 1006 1006 * ARRAYLEN(context_flags)); 1007 1007 1008 1008 for (int i=0;i < ctx_x_flag_count ;i++) ··· 2058 2058 } 2059 2059 else if (menu_id == MENU_ID(M_SETKEYS)) 2060 2060 { 2061 - keyset.view_columns = printcell_set_columns(&lists, NULL, 2061 + keyset.view_columns = printcell_set_columns(&lists, NULL, 2062 2062 ACTVIEW_HEADER, Icon_Rockbox); 2063 2063 printcell_enable(true); 2064 2064 int curcol = printcell_get_column_selected();
+12 -12
apps/plugins/lib/grey_draw.c
··· 199 199 /* nothing to draw? */ 200 200 if (y < _grey_info.clip_t || y >= _grey_info.clip_b || 201 201 x1 >= _grey_info.clip_r || x2 < _grey_info.clip_l) 202 - return; 203 - 202 + return; 203 + 204 204 /* drawmode and optimisation */ 205 205 if (vp->drawmode & DRMODE_INVERSEVID) 206 206 { ··· 251 251 unsigned char *dst, *dst_end; 252 252 void (*pfunc)(unsigned char *address); 253 253 int dwidth; 254 - 254 + 255 255 /* direction flip */ 256 256 if (y2 < y1) 257 257 { ··· 264 264 if (x < _grey_info.clip_l || x >= _grey_info.clip_r || 265 265 y1 >= _grey_info.clip_b || y2 < _grey_info.clip_t) 266 266 return; 267 - 267 + 268 268 /* clipping */ 269 269 if (y1 < _grey_info.clip_t) 270 270 y1 = _grey_info.clip_t; ··· 425 425 426 426 if (height <= 0) 427 427 return; 428 - 428 + 429 429 dwidth = _grey_info.cb_width; 430 430 dst = &_grey_info.curbuffer[ 431 431 _GREY_MULUQ(dwidth, _grey_info.vp->y - _grey_info.cb_y + y) + ··· 653 653 /* Put a string at a given pixel position, skipping first ofs pixel columns */ 654 654 void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str) 655 655 { 656 - int ch; 657 - unsigned short *ucs; 656 + ucschar_t ch; 657 + ucschar_t *ucs; 658 658 struct font* pf; 659 659 660 660 if (_grey_info.clip_b <= _grey_info.clip_t) ··· 680 680 bits = rb->font_get_bits(pf, ch); 681 681 682 682 grey_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); 683 - 683 + 684 684 x += width - ofs; 685 685 ofs = 0; 686 686 } ··· 709 709 #endif 710 710 } 711 711 712 - /* Assembler optimised helper function for copying a single line to the 712 + /* Assembler optimised helper function for copying a single line to the 713 713 * greyvalue buffer. */ 714 714 void _grey_line1(int width, unsigned char *dst, const unsigned char *src, 715 715 const unsigned char *lut); ··· 725 725 if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) 726 726 || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) 727 727 return; 728 - 728 + 729 729 /* clipping */ 730 730 if (x < 0) 731 731 { ··· 744 744 if (y + height > _grey_info.height) 745 745 height = _grey_info.height - y; 746 746 747 - src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */ 747 + src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */ 748 748 yc = y; 749 749 ye = y + height; 750 750 dst = _grey_info.values + (x << _GREY_BSHIFT); ··· 773 773 } 774 774 while (src_row < src_end); 775 775 #endif 776 - 776 + 777 777 src += stride; 778 778 } 779 779 while (++yc < ye);
+6 -6
apps/plugins/lib/kbd_helper.c
··· 22 22 #include "kbd_helper.h" 23 23 24 24 /* USAGE: 25 - unsigned short kbd[64]; 26 - unsigned short *kbd_p = kbd; 25 + ucschar_t kbd[64]; 26 + ucschar_t *kbd_p = kbd; 27 27 if (!kbd_create_layout("ABCD1234\n", kbd, sizeof(kbd))) 28 28 kbd_p = NULL; 29 29 ··· 34 34 * success returns size of buffer used 35 35 * failure returns 0 36 36 */ 37 - int kbd_create_layout(const char *layout, unsigned short *buf, int bufsz) 37 + int kbd_create_layout(const char *layout, ucschar_t *buf, int bufsz) 38 38 { 39 - unsigned short *pbuf; 39 + ucschar_t *pbuf; 40 40 const unsigned char *p = layout; 41 41 int len = 0; 42 42 int total_len = 0; 43 43 pbuf = buf; 44 - while (*p && (pbuf - buf + (ptrdiff_t) sizeof(unsigned short)) < bufsz) 44 + while (*p && (pbuf - buf + (ptrdiff_t) sizeof(ucschar_t)) < bufsz) 45 45 { 46 46 p = rb->utf8decode(p, &pbuf[len+1]); 47 47 if (pbuf[len+1] == '\n') ··· 60 60 *pbuf = len; 61 61 pbuf[len+1] = 0xFEFF; /* mark end of characters */ 62 62 total_len += len + 1; 63 - return total_len * sizeof(unsigned short); 63 + return total_len * sizeof(ucschar_t); 64 64 } 65 65 66 66 return 0;
+7 -7
apps/plugins/lib/kbd_helper.h
··· 1 1 /*************************************************************************** 2 - * __________ __ ___. 3 - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 - * \/ \/ \/ \/ \/ 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 8 * $Id$ 9 9 * 10 10 * Copyright (C) 2020 William Wilgus ··· 22 22 #define KBD_HELPER_H 23 23 24 24 /* create a custom keyboard layout for kbd_input */ 25 - int kbd_create_layout(const char *layout, unsigned short *buf, int bufsz); 25 + int kbd_create_layout(const char *layout, ucschar_t *buf, int bufsz); 26 26 27 27 #endif /* KBD_HELPER_H */
+1 -1
apps/plugins/lib/simple_viewer.c
··· 62 62 total = 0; 63 63 while(*ptr) 64 64 { 65 - unsigned short ch; 65 + ucschar_t ch; 66 66 n = ((intptr_t)rb->utf8decode(ptr, &ch) - (intptr_t)ptr); 67 67 if (rb->is_diacritic(ch, NULL)) 68 68 w = 0;
+1 -1
apps/plugins/lrcplayer.c
··· 422 422 int nlrcbrpos = 0, max_lrcbrpos; 423 423 uifont = rb->screens[0]->getuifont(); 424 424 struct font* pf = rb->font_get(uifont); 425 - unsigned short ch; 425 + ucschar_t ch; 426 426 struct snap { 427 427 int count, width; 428 428 int nword;
+2 -1
apps/plugins/lua/rocklib.c
··· 141 141 142 142 #endif 143 143 144 + // XXX this may be broken with 32-bit ucschar_t 144 145 RB_WRAP(kbd_input) 145 146 { 146 147 /*kbd_input(text, layout)* ··· 168 169 layout = NULL; 169 170 } 170 171 171 - if(!rb->kbd_input(buffer, LUAL_BUFFERSIZE, (unsigned short *)layout)) 172 + if(!rb->kbd_input(buffer, LUAL_BUFFERSIZE, (ucschar_t *)layout)) 172 173 { 173 174 luaL_addstring(&b, buffer); 174 175 luaL_pushresult(&b);
+2 -2
apps/plugins/mpegplayer/mpegplayer.c
··· 1073 1073 1074 1074 static void draw_putsxy_oriented(int x, int y, const char *str) 1075 1075 { 1076 - unsigned short ch; 1077 - unsigned short *ucs; 1076 + ucschar_t ch; 1077 + ucschar_t *ucs; 1078 1078 int ofs = MIN(x, 0); 1079 1079 struct font* pf = rb->font_get(osd.font); 1080 1080
+2 -2
apps/plugins/rockpaint.c
··· 969 969 static void buffer_putsxyofs( fb_data *buf, int buf_width, int buf_height, 970 970 int x, int y, int ofs, const unsigned char *str ) 971 971 { 972 - unsigned short ch; 973 - unsigned short *ucs; 972 + ucschar_t ch; 973 + ucschar_t *ucs; 974 974 975 975 struct font *pf = rb->font_get( FONT_UI ); 976 976 if( !pf ) pf = rb->font_get( FONT_SYSFIXED );
+2 -2
apps/plugins/tagcache/tagcache.c
··· 135 135 #define yield sleep_yield 136 136 } 137 137 138 - /* make sure tag can be displayed by font pf*/ 138 + /* make sure tag can be displayed by font pf */ 139 139 static bool text_is_displayable(struct font *pf, unsigned char *src) 140 140 { 141 - unsigned short code; 141 + ucschar_t code; 142 142 const unsigned char *ptr = src; 143 143 while(*ptr) 144 144 {
+25 -25
apps/plugins/text_viewer/tv_text_processor.c
··· 41 41 42 42 static const unsigned char *end_ptr; 43 43 44 - static unsigned short ucsbuf[TV_MAX_BLOCKS][TV_MAX_CHARS_PER_BLOCK]; 44 + static ucschar_t ucsbuf[TV_MAX_BLOCKS][TV_MAX_CHARS_PER_BLOCK]; 45 45 static unsigned char utf8buf[TV_MAX_CHARS_PER_BLOCK * (2 * 3)]; 46 46 static unsigned char *outbuf; 47 47 ··· 54 54 /* when a line is divided, this value sets true. */ 55 55 static bool is_break_line = false; 56 56 57 - static unsigned short break_chars[] = 57 + static unsigned short break_chars[] = // XXX promote to ucschar_t if we get a codepoint > 0xffff 58 58 { 59 59 0, 60 60 /* halfwidth characters */ 61 - '\t', '\n', 0x0b, 0x0c, ' ', '!', ',', '-', '.', ':', ';', '?', 0xb7, 61 + '\t', '\n', 0x0b, 0x0c, ' ', '!', ',', '-', '.', ':', ';', '?', 0xb7, 62 62 /* fullwidth characters */ 63 63 0x2010, /* hyphen */ 64 64 0x3000, /* fullwidth space */ ··· 76 76 }; 77 77 78 78 /* the characters which is not judged as space with isspace() */ 79 - static unsigned short extra_spaces[] = { 0, 0x3000 }; 79 + static unsigned short extra_spaces[] = { 0, 0x3000 }; // XXX promote to ucschar_t if we get a codepoint > 0xffff 80 80 81 81 static int tv_glyph_width(int ch) 82 82 { ··· 93 93 return rb->font_get_width(rb->font_get(preferences->font_id), ch); 94 94 } 95 95 96 - static unsigned char *tv_get_ucs(const unsigned char *str, unsigned short *ch) 96 + static unsigned char *tv_get_ucs(const unsigned char *str, ucschar_t *ch) 97 97 { 98 98 int count = 1; 99 99 unsigned char utf8_tmp[3]; ··· 148 148 return (unsigned char *)str + count; 149 149 } 150 150 151 - static void tv_decode2utf8(const unsigned short *ucs, int count) 151 + static void tv_decode2utf8(const ucschar_t *ucs, int count) 152 152 { 153 153 int i; 154 154 ··· 158 158 *outbuf = '\0'; 159 159 } 160 160 161 - static bool tv_is_line_break_char(unsigned short ch) 161 + static bool tv_is_line_break_char(ucschar_t ch) 162 162 { 163 163 size_t i; 164 164 ··· 166 166 if (preferences->word_mode == WM_CHOP) 167 167 return false; 168 168 169 - for (i = 0; i < sizeof(break_chars)/sizeof(unsigned short); i++) 169 + for (i = 0; i < sizeof(break_chars)/sizeof(ucschar_t); i++) 170 170 { 171 171 if (break_chars[i] == ch) 172 172 return true; ··· 174 174 return false; 175 175 } 176 176 177 - static bool tv_isspace(unsigned short ch) 177 + static bool tv_isspace(ucschar_t ch) 178 178 { 179 179 size_t i; 180 180 181 181 if (ch < 128 && isspace(ch)) 182 182 return true; 183 183 184 - for (i = 0; i < sizeof(extra_spaces)/sizeof(unsigned short); i++) 184 + for (i = 0; i < sizeof(extra_spaces)/sizeof(ucschar_t); i++) 185 185 { 186 186 if (extra_spaces[i] == ch) 187 187 return true; ··· 191 191 192 192 static bool tv_is_break_line_join_mode(const unsigned char *next_str) 193 193 { 194 - unsigned short ch; 194 + ucschar_t ch; 195 195 196 196 tv_get_ucs(next_str, &ch); 197 197 return tv_isspace(ch); 198 198 } 199 199 200 - static int tv_form_reflow_line(unsigned short *ucs, int chars) 200 + static int tv_form_reflow_line(ucschar_t *ucs, int chars) 201 201 { 202 - unsigned short new_ucs[TV_MAX_CHARS_PER_BLOCK]; 203 - unsigned short *p = new_ucs; 204 - unsigned short ch; 202 + ucschar_t new_ucs[TV_MAX_CHARS_PER_BLOCK]; 203 + ucschar_t *p = new_ucs; 204 + ucschar_t ch; 205 205 int i; 206 206 int k; 207 207 int expand_spaces; ··· 262 262 } 263 263 } 264 264 265 - rb->memcpy(ucs, new_ucs, sizeof(unsigned short) * TV_MAX_CHARS_PER_BLOCK); 265 + rb->memcpy(ucs, new_ucs, sizeof(ucschar_t) * TV_MAX_CHARS_PER_BLOCK); 266 266 return indent_chars + nonspace_chars + expand_spaces; 267 267 } 268 268 269 269 static void tv_align_right(int *block_chars) 270 270 { 271 - unsigned short *cur_text; 272 - unsigned short *prev_text; 273 - unsigned short ch; 271 + ucschar_t *cur_text; 272 + ucschar_t *prev_text; 273 + ucschar_t ch; 274 274 int cur_block = block_count - 1; 275 275 int prev_block; 276 276 int cur_chars; ··· 335 335 if (break_pos < prev_chars) 336 336 { 337 337 rb->memmove(cur_text + prev_chars - break_pos, 338 - cur_text, block_chars[cur_block] * sizeof(unsigned short)); 338 + cur_text, block_chars[cur_block] * sizeof(ucschar_t)); 339 339 rb->memcpy(cur_text, prev_text + break_pos, 340 - (prev_chars - break_pos) * sizeof(unsigned short)); 340 + (prev_chars - break_pos) * sizeof(ucschar_t)); 341 341 342 342 block_chars[prev_block] = break_pos; 343 343 block_chars[cur_block ] += prev_chars - break_pos; ··· 347 347 } 348 348 } 349 349 350 - static int tv_parse_text(const unsigned char *src, unsigned short *ucs, 350 + static int tv_parse_text(const unsigned char *src, ucschar_t *ucs, 351 351 int *ucs_chars, bool is_indent) 352 352 { 353 353 const unsigned char *cur = src; 354 354 const unsigned char *next = src; 355 355 const unsigned char *line_break_ptr = NULL; 356 356 const unsigned char *line_end_ptr = NULL; 357 - unsigned short ch = 0; 358 - unsigned short prev_ch; 357 + ucschar_t ch = 0; 358 + ucschar_t prev_ch; 359 359 int chars = 0; 360 360 int gw; 361 361 int line_break_width = 0; ··· 480 480 int tv_create_formed_text(const unsigned char *src, ssize_t bufsize, 481 481 int block, bool is_multi, const unsigned char **dst) 482 482 { 483 - unsigned short ch; 483 + ucschar_t ch; 484 484 int chars[block_count]; 485 485 int i; 486 486 int size = 0;
+2 -2
apps/plugins/zxbox/zxbox_keyb.c
··· 326 326 struct keyboard_parameters { 327 327 const unsigned char* default_kbd; 328 328 int DEFAULT_LINES; 329 - unsigned short kbd_buf[KBD_BUF_SIZE]; 329 + ucschar_t kbd_buf[KBD_BUF_SIZE]; 330 330 int nchars; 331 331 int font_w; 332 332 int font_h; ··· 358 358 int editpos, len_utf8; 359 359 #endif 360 360 /* int statusbar_size = global_settings.statusbar ? STATUSBAR_HEIGHT : 0;*/ 361 - unsigned short ch/*, tmp, hlead = 0, hvowel = 0, htail = 0*/; 361 + ucschar_t ch/*, tmp, hlead = 0, hvowel = 0, htail = 0*/; 362 362 /*bool hangul = false;*/ 363 363 unsigned char *utf8; 364 364 const unsigned char *p;
+33 -33
apps/recorder/keyboard.c
··· 90 90 struct keyboard_parameters 91 91 { 92 92 struct viewport *kbd_viewports; 93 - unsigned short kbd_buf[KBD_BUF_SIZE]; 94 - unsigned short *kbd_buf_ptr; 93 + ucschar_t kbd_buf[KBD_BUF_SIZE]; 94 + ucschar_t *kbd_buf_ptr; 95 95 unsigned short max_line_len; 96 96 int default_lines; 97 - int last_k; 98 - int last_i; 99 - int font_w; 100 - int font_h; 101 - int text_w; 97 + unsigned int last_k; 98 + unsigned int last_i; 99 + unsigned short font_w; 100 + unsigned short font_h; 101 + unsigned int text_w; 102 102 int curfont; 103 103 int main_y; 104 104 #ifdef HAVE_MORSE_INPUT ··· 128 128 int editpos; /* Edit position on all screens */ 129 129 bool cur_blink; /* Cursor on/off flag */ 130 130 bool hangul; 131 - unsigned short hlead, hvowel, htail; 131 + ucschar_t hlead, hvowel, htail; 132 132 #ifdef HAVE_MORSE_INPUT 133 133 bool morse_mode; 134 134 bool morse_reading; ··· 158 158 { 159 159 /*Note: viewports are initialized to vp_default by kbd_create_viewports */ 160 160 161 - int sc_w = sc->getwidth(); 162 - int sc_h = sc->getheight(); 161 + unsigned short sc_w = sc->getwidth(); 162 + unsigned short sc_h = sc->getheight(); 163 163 164 164 /* TEXT */ 165 165 struct viewport *vp = &kbd_vp[eKBD_VP_TEXT]; 166 166 /* make sure height is even for the text box */ 167 - int text_height = (MAX(pm->font_h, get_icon_height(sc->screen_type)) & ~1) + 2; 167 + unsigned short text_height = (MAX(pm->font_h, (unsigned int)get_icon_height(sc->screen_type)) & ~1) + 2; 168 168 vp->x = 0; /* LEFT */ 169 169 vp->y = 0; /* TOP */ 170 170 vp->width = sc_w; ··· 224 224 int fd; 225 225 int i, line_len, max_line_len; 226 226 unsigned char buf[4]; 227 - unsigned short *pbuf; 227 + ucschar_t *pbuf; 228 228 229 229 if (filename == NULL) 230 230 { ··· 245 245 /* check how many bytes to read for this character */ 246 246 static const unsigned char sizes[4] = { 0x80, 0xe0, 0xf0, 0xf5 }; 247 247 size_t count; 248 - unsigned short ch; 248 + ucschar_t ch; 249 249 250 250 for (count = 0; count < ARRAYLEN(sizes); count++) 251 251 { ··· 297 297 struct keyboard_parameters *pm = &kbd_param[l]; 298 298 #if NB_SCREENS > 1 299 299 if (l > 0) 300 - memcpy(pm->kbd_buf, kbd_param[0].kbd_buf, i*sizeof(unsigned short)); 300 + memcpy(pm->kbd_buf, kbd_param[0].kbd_buf, i*sizeof(ucschar_t)); 301 301 #endif 302 302 /* initialize parameters */ 303 303 pm->x = pm->y = pm->page = 0; ··· 309 309 } 310 310 311 311 /* helper function to spell a char */ 312 - static void kbd_spellchar(unsigned short c) 312 + static void kbd_spellchar(ucschar_t c) 313 313 { 314 314 unsigned char tmp[5]; 315 315 /* store char to pass to talk_spell */ ··· 322 322 talk_spell(tmp, false); 323 323 } 324 324 325 - static void kbd_inschar(struct edit_state *state, unsigned short ch) 325 + static void kbd_inschar(struct edit_state *state, ucschar_t ch) 326 326 { 327 327 int i, j, len; 328 328 unsigned char tmp[4]; ··· 361 361 } 362 362 363 363 /* Lookup k value based on state of param (pm) */ 364 - static unsigned short get_kbd_ch(struct keyboard_parameters *pm, int x, int y) 364 + static ucschar_t get_kbd_ch(struct keyboard_parameters *pm, int x, int y) 365 365 { 366 - int i = 0, k = pm->page*pm->lines + y, n; 367 - unsigned short *pbuf; 366 + unsigned int n, i = 0, k = pm->page*pm->lines + y; 367 + ucschar_t *pbuf; 368 368 if (k >= pm->last_k) 369 369 { 370 370 i = pm->last_i; ··· 406 406 static void kbd_move_picker_vertical(struct keyboard_parameters *pm, 407 407 struct edit_state *state, int dir); 408 408 409 - int kbd_input(char* text, int buflen, unsigned short *kbd) 409 + int kbd_input(char* text, int buflen, ucschar_t *kbd) 410 410 { 411 411 bool done = false; 412 412 struct keyboard_parameters * const param = kbd_param; 413 413 struct edit_state state; 414 - unsigned short ch; 414 + ucschar_t ch; 415 415 int ret = 0; /* assume success */ 416 416 FOR_NB_SCREENS(l) 417 417 { ··· 449 449 FOR_NB_SCREENS(l) 450 450 { 451 451 struct keyboard_parameters *pm = &param[l]; 452 - unsigned short *pbuf; 452 + ucschar_t *pbuf; 453 453 const unsigned char *p; 454 454 int len = 0; 455 455 ··· 800 800 { 801 801 struct font* font; 802 802 const unsigned char *p; 803 - unsigned short ch, *pbuf; 804 - int i, w; 803 + ucschar_t ch, *pbuf; 804 + unsigned int i, w; 805 805 #ifdef HAVE_TOUCHSCREEN 806 806 pm->show_buttons = (sc->screen_type == SCREEN_MAIN && 807 807 (touchscreen_get_mode() == TOUCHSCREEN_POINT)); ··· 812 812 pm->font_h = font->height; 813 813 814 814 /* check if FONT_UI fits the screen */ 815 - if (2*pm->font_h + 3 > sc->getheight()) 815 + if (pm->font_h*2 + 3 > sc->getheight()) 816 816 { 817 817 pm->curfont = FONT_SYSFIXED; 818 818 font = font_get(FONT_SYSFIXED); ··· 858 858 { 859 859 (void) state; 860 860 struct viewport *vp = &pm->kbd_viewports[eKBD_VP_PICKER]; 861 - int icon_w, sc_w, sc_h; 861 + unsigned int icon_w, sc_w, sc_h; 862 862 int i, total_lines; 863 - unsigned short *pbuf; 863 + ucschar_t *pbuf; 864 864 /* calculate how many characters to put in a row. */ 865 865 icon_w = get_icon_width(sc->screen_type); 866 866 ··· 970 970 x = 0; 971 971 y = 0; 972 972 outline[1] = '\0'; 973 - 973 + 974 974 /* Draw morse code table with code descriptions. */ 975 975 for (i = 0; morse_alphabets[i] != '\0'; i++) { 976 976 int morse_code; ··· 1024 1024 /* draw page */ 1025 1025 int i, j; 1026 1026 int w, h; 1027 - unsigned short ch; 1027 + ucschar_t ch; 1028 1028 unsigned char *utf8; 1029 1029 1030 1030 sc->setfont(pm->curfont); ··· 1071 1071 int sc_w = vp->width; 1072 1072 int y = (vp->height - pm->font_h) / 2; 1073 1073 1074 - 1074 + 1075 1075 int text_margin = (sc_w - pm->text_w * pm->max_chars_text) / 2; 1076 1076 1077 1077 #if 0 ··· 1265 1265 struct edit_state *state) 1266 1266 { 1267 1267 /* find input char */ 1268 - unsigned short ch = get_kbd_ch(pm, pm->x, pm->y); 1268 + ucschar_t ch = get_kbd_ch(pm, pm->x, pm->y); 1269 1269 1270 1270 /* check for hangul input */ 1271 1271 if (ch >= 0x3131 && ch <= 0x3163) 1272 1272 { 1273 - unsigned short tmp; 1273 + ucschar_t tmp; 1274 1274 1275 1275 if (!state->hangul) 1276 1276 { ··· 1335 1335 1336 1336 static void kbd_backspace(struct edit_state *state) 1337 1337 { 1338 - unsigned short ch; 1338 + ucschar_t ch; 1339 1339 if (state->hangul) 1340 1340 { 1341 1341 if (state->htail)
+5 -5
bootloader/iriver_h1x0.c
··· 600 600 return 0; 601 601 } 602 602 603 - unsigned short *bidi_l2v(const unsigned char *str, int orientation) 603 + ucschar_t *bidi_l2v(const unsigned char *str, int orientation) 604 604 { 605 - static unsigned short utf16_buf[SCROLL_LINE_SIZE]; 606 - unsigned short *target; 605 + static ucschar_t utf_buf[SCROLL_LINE_SIZE]; 606 + ucschar_t *target; 607 607 (void)orientation; 608 608 609 - target = utf16_buf; 609 + target = utf_buf; 610 610 611 611 while (*str) 612 612 str = utf8decode(str, target++); 613 613 *target = 0; 614 - return utf16_buf; 614 + return utf_buf; 615 615 }
+5 -5
bootloader/iriver_h300.c
··· 660 660 return 0; 661 661 } 662 662 663 - unsigned short *bidi_l2v(const unsigned char *str, int orientation) 663 + ucschar_t *bidi_l2v(const unsigned char *str, int orientation) 664 664 { 665 - static unsigned short utf16_buf[SCROLL_LINE_SIZE]; 666 - unsigned short *target; 665 + static ucschar_t utf_buf[SCROLL_LINE_SIZE]; 666 + ucschar_t *target; 667 667 (void)orientation; 668 668 669 - target = utf16_buf; 669 + target = utf_buf; 670 670 671 671 while (*str) 672 672 str = utf8decode(str, target++); 673 673 *target = 0; 674 - return utf16_buf; 674 + return utf_buf; 675 675 }
+5 -5
docs/PLUGIN_API
··· 225 225 \param amplitude 226 226 \description 227 227 228 - unsigned short *bidi_l2v( const unsigned char *str, int orientation ) 228 + ucschar_t *bidi_l2v( const unsigned char *str, int orientation ) 229 229 \param str 230 230 \param orientation 231 231 \return ··· 407 407 \return 408 408 \description 409 409 410 - const unsigned char *font_get_bits( struct font *pf, unsigned short char_code ) 410 + const unsigned char *font_get_bits( struct font *pf, ucschar_t char_code ) 411 411 \param pf 412 412 \param char_code 413 413 \return 414 414 \description 415 415 416 - const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs) 416 + const unsigned char* utf8decode(const unsigned char *utf8, ucschar_t *ucs) 417 417 \group unicode stuff 418 418 \param utf8 419 419 \param ucs ··· 747 747 \return 748 748 \description 749 749 750 - int font_get_width(struct font* pf, unsigned short char_code) 750 + int font_get_width(struct font* pf, ucschar_t char_code) 751 751 \param pf 752 752 \param char_code 753 753 \return ··· 972 972 \return 973 973 \description 974 974 975 - int kbd_input(char* buffer, int buflen, unsigned short *kbd) 975 + int kbd_input(char* buffer, int buflen, ucschar_t *kbd) 976 976 \group misc 977 977 \param buffer 978 978 \param buflen
+2
firmware/arabjoin.h
··· 1 + /* Note these are not ucschar_t becuase all arabic 2 + codepoints are <16bit, so no need to waste table space */ 1 3 typedef struct { 2 4 unsigned short isolated; 3 5 unsigned short final;
+21 -22
firmware/bidi.c
··· 44 44 #define XOR(a,b) ((a||b) && !(a&&b)) 45 45 46 46 #ifndef BOOTLOADER 47 - static const arab_t * arab_lookup(unsigned short uchar) 47 + static const arab_t * arab_lookup(ucschar_t uchar) 48 48 { 49 49 if (uchar >= 0x621 && uchar <= 0x63a) 50 50 return &(jointable[uchar - 0x621]); ··· 57 57 return 0; 58 58 } 59 59 60 - static void arabjoin(unsigned short * stringprt, int length) 60 + static void arabjoin(ucschar_t *stringprt, int length) 61 61 { 62 62 bool connected = false; 63 - unsigned short * writeprt = stringprt; 63 + ucschar_t *writeprt = stringprt; 64 64 65 65 const arab_t * prev = 0; 66 66 const arab_t * cur; 67 67 const arab_t * ligature = 0; 68 - short uchar; 68 + ucschar_t uchar; 69 69 70 70 int i; 71 71 for (i = 0; i <= length; i++) { ··· 135 135 } 136 136 #endif /* !BOOTLOADER */ 137 137 138 - unsigned short *bidi_l2v(const unsigned char *str, int orientation) 138 + ucschar_t *bidi_l2v(const unsigned char *str, int orientation) 139 139 { 140 - static unsigned short utf16_buf[SCROLL_LINE_SIZE]; 141 - unsigned short *target, *tmp; 140 + static ucschar_t utf_buf[SCROLL_LINE_SIZE]; 141 + ucschar_t *target, *tmp; 142 142 #ifndef BOOTLOADER 143 - static unsigned short bidi_buf[SCROLL_LINE_SIZE]; 144 - unsigned short *heb_str; /* *broken_str */ 143 + static ucschar_t bidi_buf[SCROLL_LINE_SIZE]; 144 + ucschar_t *heb_str; /* *broken_str */ 145 145 int block_start, block_end, block_type, block_length, i; 146 146 int length = utf8length(str); 147 147 length=length>=SCROLL_LINE_SIZE?SCROLL_LINE_SIZE-1:length; ··· 152 152 153 153 tmp = str; 154 154 */ 155 - target = tmp = utf16_buf; 156 - while (*str && target < &utf16_buf[SCROLL_LINE_SIZE-1]) 155 + target = tmp = utf_buf; 156 + while (*str && target < &utf_buf[SCROLL_LINE_SIZE-1]) 157 157 str = utf8decode(str, target++); 158 158 *target = 0; 159 159 160 160 #ifdef BOOTLOADER 161 161 (void)orientation; 162 - return utf16_buf; 163 - 162 + return utf_buf; 163 + 164 164 #else /* !BOOTLOADER */ 165 - if (target == utf16_buf) /* empty string */ 165 + if (target == utf_buf) /* empty string */ 166 166 return target; 167 167 168 168 /* properly join any arabic chars */ 169 - arabjoin(utf16_buf, length); 169 + arabjoin(utf_buf, length); 170 170 171 171 block_start=block_end=block_length=0; 172 172 ··· 204 204 205 205 for (i=block_start; i<=block_end; i++) { 206 206 *target = (block_type == orientation) ? 207 - *(utf16_buf+i) : *(utf16_buf+block_end-i+block_start); 207 + *(utf_buf+i) : *(utf_buf+block_end-i+block_start); 208 208 if (block_type!=orientation) { 209 209 switch (*target) { 210 210 case '(': ··· 226 226 *target = 0; 227 227 228 228 #if 0 /* Is this code really necessary? */ 229 - broken_str = utf16_buf; 229 + broken_str = utf_buf; 230 230 begin=end=length-1; 231 231 target = broken_str; 232 232 ··· 246 246 if (char_count==max_chars) { /* try to avoid breaking words */ 247 247 int new_char_count = char_count; 248 248 int new_begin = begin; 249 - 249 + 250 250 while (new_char_count>0) { 251 251 if (_isblank(heb_str[new_begin]) || 252 252 _isnewline(heb_str[new_begin])) { ··· 261 261 } 262 262 } 263 263 orig_begin=begin; 264 - 264 + 265 265 /* if (_isblank(heb_str[begin])) { 266 266 heb_str[begin]='\n'; 267 267 } */ 268 - 268 + 269 269 /* skip leading newlines */ 270 270 while (begin<=end && _isnewline(heb_str[begin])) { 271 271 begin++; ··· 282 282 target++; 283 283 } 284 284 begin=orig_begin; 285 - 285 + 286 286 if (begin<=0) { 287 287 *target = 0; 288 288 break; ··· 295 295 return heb_str; 296 296 #endif /* !BOOTLOADER */ 297 297 } 298 -
+13 -13
firmware/common/diacritic.c
··· 28 28 #include "system.h" 29 29 30 30 #define DIAC_NUM_RANGES (ARRAYLEN(diac_ranges)) 31 - #define DIAC_RTL (1 << 7) 32 - #define DIAC_CNT (0xFF ^ DIAC_RTL) 31 + #define DIAC_RTL (1 << 15) 32 + #define DIAC_CNT (0xFFFF ^ DIAC_RTL) 33 33 34 34 /* Each diac_range_ struct defines a Unicode range that begins with 35 35 * N diacritic characters, and continues with non-diacritic characters up to the ··· 39 39 40 40 struct diac_range 41 41 { 42 - uint16_t base; 43 - uint8_t info; /* [RTL:1 CNT:7] */ 42 + uint16_t base; /* Not ucschar_t until we need >16b */ 43 + uint16_t info; /* [RTL:1 CNT:15] */ 44 44 }; 45 45 46 46 #define DIAC_RANGE_ENTRY(first_diac, first_non_diac, is_rtl) \ ··· 51 51 static const struct diac_range diac_ranges[] = 52 52 { 53 53 DIAC_RANGE_ENTRY(0x0000, 0x0000, 0), 54 - DIAC_RANGE_ENTRY(FIRST_DIACRITIC, 0x0370, 0), 54 + DIAC_RANGE_ENTRY(FIRST_DIACRITIC, 0x0370, 0), /* v1 - v4.1 */ 55 55 DIAC_RANGE_ENTRY(0x0483, 0x048a, 0), 56 56 DIAC_RANGE_ENTRY(0x0591, 0x05be, 1), 57 57 DIAC_RANGE_ENTRY(0x05bf, 0x05c0, 1), ··· 146 146 DIAC_RANGE_ENTRY(0x19c8, 0x19ca, 0), 147 147 DIAC_RANGE_ENTRY(0x1a17, 0x1a1c, 0), 148 148 DIAC_RANGE_ENTRY(0x1a55, 0x1a80, 0), 149 + DIAC_RANGE_ENTRY(0x1ab0, 0x1b00, 0), /* v7.0 */ 149 150 DIAC_RANGE_ENTRY(0x1b00, 0x1b05, 0), 150 151 DIAC_RANGE_ENTRY(0x1b34, 0x1b45, 0), 151 152 DIAC_RANGE_ENTRY(0x1b6b, 0x1b74, 0), ··· 156 157 DIAC_RANGE_ENTRY(0x1cd4, 0x1ce9, 0), 157 158 DIAC_RANGE_ENTRY(0x1ced, 0x1cee, 0), 158 159 DIAC_RANGE_ENTRY(0x1cf2, 0x1cf3, 0), 159 - DIAC_RANGE_ENTRY(0x1dc0, 0x1e00, 0), 160 - DIAC_RANGE_ENTRY(0x20d0, 0x20f1, 0), 160 + DIAC_RANGE_ENTRY(0x1dc0, 0x1e00, 0), /* v4.1 - v5.2 */ 161 + DIAC_RANGE_ENTRY(0x20d0, 0x2100, 0), /* v1.0 - v5.1 */ 161 162 DIAC_RANGE_ENTRY(0x2cef, 0x2cf2, 0), 162 - DIAC_RANGE_ENTRY(0x2de0, 0x2e00, 0), 163 + DIAC_RANGE_ENTRY(0x2de0, 0x2e00, 0), /* v5.1 */ 163 164 DIAC_RANGE_ENTRY(0x302a, 0x3030, 0), 164 165 DIAC_RANGE_ENTRY(0x3099, 0x309b, 0), 165 166 DIAC_RANGE_ENTRY(0xa66f, 0xa673, 0), ··· 188 189 DIAC_RANGE_ENTRY(0xabe3, 0xabeb, 0), 189 190 DIAC_RANGE_ENTRY(0xabec, 0xabee, 0), 190 191 DIAC_RANGE_ENTRY(0xfb1e, 0xfb1f, 0), 191 - DIAC_RANGE_ENTRY(0xfe20, 0xfe27, 0), 192 + DIAC_RANGE_ENTRY(0xfe20, 0xfe30, 0), /* v1.0 - v8.0 */ 192 193 DIAC_RANGE_ENTRY(0xfe70, 0xfe70, 1), 193 194 DIAC_RANGE_ENTRY(0xff00, 0xff00, 0), 194 195 DIAC_RANGE_ENTRY(0xffff, 0xffff, 0), ··· 196 197 197 198 #define MRU_MAX_LEN 32 198 199 199 - bool is_diacritic(const unsigned short char_code, bool *is_rtl) 200 + bool is_diacritic(const ucschar_t char_code, bool *is_rtl) 200 201 { 201 202 static uint8_t mru_len = 0; 202 203 static uint8_t diacritic_mru[MRU_MAX_LEN]; ··· 209 210 /* Search in MRU */ 210 211 for (mru = 0, i = 0; mru < mru_len; mru++) 211 212 { 212 - 213 213 /* Items shifted >> 1 */ 214 214 itmp = i; 215 215 i = diacritic_mru[mru]; ··· 250 250 if (is_rtl) 251 251 *is_rtl = ((DIAC_RTL & info) == DIAC_RTL); 252 252 253 - return (char_code < diac->base + (info & DIAC_CNT)); 253 + return (char_code < (diac->base + (info & DIAC_CNT))); 254 254 } 255 255 #else /*BOOTLOADER*/ 256 - inline bool is_diacritic(const unsigned short char_code, bool *is_rtl) 256 + inline bool is_diacritic(const ucschar_t char_code, bool *is_rtl) 257 257 { 258 258 (void)char_code; 259 259 if (is_rtl)
+30 -5
firmware/common/unicode.c
··· 127 127 128 128 /* non-default codepage table buffer (cannot be bufalloced! playback itself 129 129 may be making the load request) */ 130 - static unsigned short codepage_table[MAX_CP_TABLE_SIZE+1]; 130 + static unsigned short codepage_table[MAX_CP_TABLE_SIZE+1]; // XXX convert to ucschar_t if we ever need > 16bit mappings? 131 131 132 132 #if defined(APPLICATION) && defined(__linux__) 133 133 static const char * const name_codepages_linux[NUM_CODEPAGES+1] = ··· 344 344 cp_lock_leave(); 345 345 346 346 while (count-- && utf8_size > 0) { 347 - unsigned short ucs, tmp; 347 + ucschar_t ucs, tmp; 348 348 349 349 if (*iso < 128 || cp == UTF_8) /* Already UTF-8 */ 350 350 { ··· 511 511 return l; 512 512 } 513 513 514 + /* Take a utf8 string and return the encoded length in utf16 code units */ 515 + unsigned long utf16len_utf8(const unsigned char *utf8) 516 + { 517 + ucschar_t cp; 518 + unsigned long length = 0; 519 + while (*utf8) { 520 + utf8 = utf8decode(utf8, &cp); 521 + #ifdef UNICODE32 522 + if (cp >= 0x10000) 523 + length++; 524 + #endif 525 + length++; 526 + } 527 + 528 + return length; 529 + } 530 + 514 531 /* Decode 1 UTF-8 char and return a pointer to the next char. */ 515 - const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs) 532 + const unsigned char* utf8decode(const unsigned char *utf8, ucschar_t *ucs) 516 533 { 517 534 unsigned char c = *utf8++; 518 535 unsigned long code; ··· 552 569 /* Invalid UTF-8 char */ 553 570 code = 0xfffd; 554 571 } 555 - /* currently we don't support chars above U-FFFF */ 556 - *ucs = (code < 0x10000) ? code : 0xfffd; 572 + 573 + #ifdef UNICODE32 574 + if (code > 0x10ffff) 575 + code = 0xfffd; 576 + #else 577 + if (code > 0xffff) 578 + code = 0xfffd; 579 + #endif 580 + 581 + *ucs = code; 557 582 return utf8; 558 583 } 559 584
+40 -9
firmware/drivers/fat.c
··· 747 747 /* so far so good; save entry information */ 748 748 lnparse->ord = ord; 749 749 750 + /* Treat entries as opaque 16-bit values; 751 + utf8decode happens in fatlong_parse_finish() */ 750 752 uint16_t *ucsp = fatent->ucssegs[ord - 1 + 5]; 751 753 unsigned int i = longent_char_first(); 752 754 ··· 797 799 /* ensure the last segment is NULL-terminated if it is filled */ 798 800 fatent->ucssegs[lnparse->ord_max + 5][0] = 0x0000; 799 801 800 - for (uint16_t *ucsp = fatent->ucssegs[5], ucc = *ucsp; 801 - ucc; ucc = *++ucsp) 802 + unsigned long ucc; /* Decoded codepoint */ 803 + uint16_t *ucsp, ucs; 804 + for (ucsp = fatent->ucssegs[5], ucs=*ucsp; ucs; ucs = *++ucsp) 802 805 { 803 806 /* end should be hit before ever seeing padding */ 804 - if (ucc == 0xffff) 807 + if (ucs == 0xffff) 805 808 return false; 809 + 810 + #ifdef UNICODE32 811 + /* Check for a surrogate UTF16 pair */ 812 + if (ucs >= 0xd800 && ucs < 0xdc00 && 813 + *(ucsp+1) >= 0xdc00 && *(ucsp+1) < 0xe000) { 814 + ucc = 0x10000 + (((ucs & 0x3ff) << 10) | (*(ucsp+1) & 0x3ff)); 815 + ucsp++; 816 + } else 817 + #endif 818 + ucc = ucs; 806 819 807 820 if ((p = utf8encode(ucc, p)) - name > FAT_DIRENTRY_NAME_MAX) 808 821 return false; ··· 1612 1625 1613 1626 for (unsigned long i = 0; i < ucspadlen; i++) 1614 1627 { 1615 - if (i < ucslen) 1628 + if (i < ucslen) { 1629 + #ifdef UNICODE32 1630 + ucschar_t tmp; 1631 + name = utf8decode(name, &tmp); 1632 + /* For codepoints > U+FFFF we will need to use a UTF16 surrogate 1633 + pair. 'ucslen' already takes this into account! */ 1634 + if (tmp < 0x10000) { 1635 + ucsname[i] = tmp; 1636 + } else { 1637 + tmp -= 0x10000; 1638 + ucsname[i++] = 0xd800 | ((tmp >> 10) & 0x3ff); /* High */ 1639 + ucsname[i] = 0xdc00 | (tmp & 0x3ff); /* Low */ 1640 + } 1641 + #else 1616 1642 name = utf8decode(name, &ucsname[i]); 1617 - else if (i == ucslen) 1643 + #endif 1644 + } else if (i == ucslen) { 1618 1645 ucsname[i] = 0x0000; /* name doesn't fill last block */ 1619 - else /* i > ucslen */ 1646 + } else /* i > ucslen */ { 1620 1647 ucsname[i] = 0xffff; /* pad-out to end */ 1648 + } 1621 1649 } 1622 1650 1623 1651 dc_lock_cache(); ··· 1744 1772 create_dos_name(basisname, name, &n); 1745 1773 randomize_dos_name(shortname, basisname, &n); 1746 1774 1747 - /* one dir entry needed for every 13 characters of filename, 1748 - plus one entry for the short name */ 1749 - ucslen = utf8length(name); 1775 + /* one dir entry needed for every 13 utf16 "code units" 1776 + of filename, plus one entry for the short name. 1777 + Keep in mind that a unicode character can take up to 1778 + two code units! 1779 + */ 1780 + ucslen = utf16len_utf8(name); 1750 1781 if (ucslen > 255) 1751 1782 FAT_ERROR(-2); /* name is too long */ 1752 1783
+5 -5
firmware/drivers/lcd-bitmap-common.c
··· 385 385 /* put a string at a given pixel position, skipping first ofs pixel columns */ 386 386 static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) 387 387 { 388 - unsigned short *ucs; 388 + ucschar_t *ucs; 389 389 struct viewport *vp = LCDFN(current_viewport); 390 390 font_lock(vp->font, true); 391 391 struct font* pf = font_get(vp->font); ··· 429 429 bool is_rtl, is_diac; 430 430 const unsigned char *bits; 431 431 int width, base_width, base_ofs = 0; 432 - const unsigned short next_ch = ucs[1]; 432 + const ucschar_t next_ch = ucs[1]; 433 433 434 434 if (x >= vp->width) 435 435 break; ··· 447 447 { 448 448 if (!rtl_next_non_diac_width) 449 449 { 450 - const unsigned short *u; 450 + const ucschar_t *u; 451 451 452 452 /* Jump to next non-diacritic char, and calc its width */ 453 453 for (u = &ucs[1]; *u && IS_DIACRITIC(*u); u++); ··· 529 529 /* put a string at a given pixel position, skipping first ofs pixel columns */ 530 530 static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) 531 531 { 532 - unsigned short *ucs; 532 + ucschar_t *ucs; 533 533 struct viewport *vp = LCDFN(current_viewport); 534 534 struct font* pf = font_get(vp->font); 535 535 const unsigned char *bits; ··· 567 567 /* allow utf but no diacritics or rtl lang */ 568 568 for (ucs = bidi_l2v(str, 1); *ucs; ucs++) 569 569 { 570 - const unsigned short next_ch = ucs[1]; 570 + const ucschar_t next_ch = ucs[1]; 571 571 572 572 if (x >= vp->width) 573 573 break;
+1 -1
firmware/export/bidi.h
··· 21 21 #ifndef BIDI_H 22 22 #define BIDI_H 23 23 24 - extern unsigned short *bidi_l2v(const unsigned char *str, int orientation); 24 + ucschar_t *bidi_l2v(const unsigned char *str, int orientation); 25 25 26 26 #endif /* BIDI_H */
+7
firmware/export/config.h
··· 1461 1461 #error "HAVE_LCD_SLEEP_SETTING requires HAVE_LCD_SLEEP" 1462 1462 #endif 1463 1463 1464 + // XXX Figure out a better place to put this? 1465 + #ifdef UNICODE32 1466 + #define ucschar_t unsigned int 1467 + #else 1468 + #define ucschar_t unsigned short 1469 + #endif 1470 + 1464 1471 #endif /* __CONFIG_H__ */
+5
firmware/export/cpu.h
··· 18 18 * KIND, either express or implied. 19 19 * 20 20 ****************************************************************************/ 21 + #ifndef __CPU_H 22 + #define __CPU_H 23 + 21 24 #include "config.h" 22 25 23 26 #if CONFIG_CPU == MCF5249 ··· 80 83 #if CONFIG_CPU == STM32H743 81 84 #include "cpu-stm32h743.h" 82 85 #endif 86 + 87 + #endif /* __CPU_H */
+10 -10
firmware/export/font.h
··· 86 86 int maxwidth; /* max width in pixels*/ 87 87 unsigned int height; /* height in pixels*/ 88 88 int ascent; /* ascent (baseline) height*/ 89 - int firstchar; /* first character in bitmap*/ 89 + unsigned int firstchar; /* first character in bitmap*/ 90 90 int size; /* font size in glyphs*/ 91 91 int depth; /* depth of the font, 0=1bit and 1=4bit */ 92 92 const unsigned char *bits; /* 8-bit column bitmap data*/ ··· 95 95 const unsigned char *width; /* character widths or NULL if fixed*/ 96 96 int defaultchar; /* default char (not glyph index)*/ 97 97 int32_t bits_size; /* # bytes of glyph bits*/ 98 - 98 + 99 99 /* file, buffer and cache management */ 100 100 int fd; /* fd for the font file. >= 0 if cached */ 101 101 int fd_width; /* fd for the font file. >= 0 if cached */ 102 - int fd_offset; /* fd for the font file. >= 0 if cached */ 102 + int fd_offset; /* fd for the font file. >= 0 if cached */ 103 103 int handle; /* core_allocator handle */ 104 - unsigned char *buffer_start; /* buffer to store the font in */ 105 - unsigned char *buffer_position; /* position in the buffer */ 104 + unsigned char *buffer_start; /* buffer to store the font in */ 105 + unsigned char *buffer_position; /* position in the buffer */ 106 106 unsigned char *buffer_end; /* end of the buffer */ 107 107 size_t buffer_size; /* size of the buffer in bytes */ 108 108 bool disabled; /* font disabled (use blank as fallback if not in cache) */ 109 - #ifndef __PCTOOL__ 109 + #ifndef __PCTOOL__ 110 110 struct font_cache cache; 111 111 uint32_t file_width_offset; /* offset to file width data */ 112 112 uint32_t file_offset_offset; /* offset to file offset data */ 113 113 int long_offset; 114 - #endif 115 - 114 + #endif 115 + 116 116 }; 117 117 118 118 /* font routines*/ ··· 134 134 struct font* font_get(int font); 135 135 int font_getstringnsize(const unsigned char *str, size_t maxbytes, int *w, int *h, int fontnumber); 136 136 int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber); 137 - int font_get_width(struct font* ft, unsigned short ch); 138 - const unsigned char * font_get_bits(struct font* ft, unsigned short ch); 137 + int font_get_width(struct font* ft, ucschar_t ch); 138 + const unsigned char * font_get_bits(struct font* ft, ucschar_t ch); 139 139 140 140 #endif
+1 -2
firmware/export/hangul.h
··· 21 21 22 22 extern const char jamo_table[51][3]; 23 23 24 - unsigned short hangul_join(unsigned short lead, unsigned short vowel, 25 - unsigned short tail); 24 + ucschar_t hangul_join(ucschar_t lead, ucschar_t vowel, ucschar_t tail);
+78 -43
firmware/font.c
··· 53 53 #define FONT_EXT "fnt" 54 54 #define GLYPH_CACHE_EXT "gc" 55 55 56 + #ifdef UNICODE32 57 + #define FC_HEADER_VAL 0x01000020 58 + #else 59 + #define FC_HEADER_VAL 0x01000010 60 + #endif 61 + 56 62 /* max static loadable font buffer size */ 57 63 #ifndef MAX_FONT_SIZE 58 64 #if LCD_HEIGHT > 64 ··· 182 188 183 189 static short readshort(struct font *pf) 184 190 { 185 - unsigned short s; 191 + uint16_t s; 186 192 187 193 s = *pf->buffer_position++ & 0xff; 188 194 s |= (*pf->buffer_position++ << 8); ··· 361 367 size_t bufsize; 362 368 363 369 /* LRU bytes per glyph */ 364 - bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) + 365 - sizeof( unsigned short); 370 + bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) + 371 + sizeof(unsigned short); 366 372 /* Image bytes per glyph */ 367 373 bufsize += glyph_bytes(pf, pf->maxwidth); 368 374 bufsize *= glyphs; ··· 371 377 } 372 378 373 379 static struct font* font_load_header(int fd, struct font *pheader, 374 - struct font *pf, 380 + struct font *pf, 375 381 uint32_t *nwidth, uint32_t *noffset) 376 382 { 377 383 /* Load the header. Readshort() and readlong() * ··· 420 426 if ( fd < 0 ) 421 427 return -1; 422 428 429 + #ifdef UNICODE32 430 + if (glyphs && glyphs < 3) 431 + glyphs = 3; /* Guarantee we'll always have at least 2 after alignment */ 432 + #else 433 + if (glyphs && glyphs < 2) 434 + glyphs = 2; /* Guarantee we'll always have at least 1 after alignment */ 435 + #endif 436 + 423 437 /* load font struct f with file header */ 424 438 int file_size = filesize( fd ); 425 439 struct font header; 426 440 struct font f; 427 441 428 - uint32_t nwidth, noffset; 442 + uint32_t nwidth, noffset; 429 443 if ( !font_load_header( fd, &header, &f, &nwidth, &noffset ) 430 444 #if LCD_DEPTH < 16 431 445 || f.depth 432 - #endif 446 + #endif 433 447 ) 434 448 { 435 449 close(fd); ··· 458 472 cached = true; 459 473 else 460 474 bufsize = file_size; 461 - 475 + 462 476 /* check already loaded */ 463 477 int font_id = find_font_index(path); 464 478 ··· 503 517 return -1; 504 518 } 505 519 pd->refcount++; 506 - //printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount); 520 + //printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount); 507 521 close(fd); 508 522 return font_id; 509 523 } ··· 522 536 return -1; 523 537 font_id = open_slot; 524 538 size_t path_bufsz = MAX(path_len + 1, 64); /* enough size for common case */ 525 - /* allocate mem */ 539 + /* allocate mem */ 526 540 int handle = core_alloc_ex( 527 541 bufsize + path_bufsz + sizeof( struct buflib_alloc_data ), 528 542 &buflibops ); ··· 574 588 pf->fd_offset = -1; 575 589 } 576 590 else 577 - { 591 + { 578 592 lseek( fd, 0, SEEK_SET); 579 593 read(fd, pf->buffer_start, pf->buffer_size); 580 594 ··· 723 737 { 724 738 struct font* pf = callback_data; 725 739 726 - unsigned short char_code = p->_char_code; 740 + ucschar_t char_code = p->_char_code; 727 741 int fd; 728 742 729 743 lock_font_handle(pf->handle, true); ··· 788 802 * when the font file is closed during USB */ 789 803 unsigned char *cache_buf = pf->buffer_start + bitmap_size; 790 804 size_t cache_size = pf->buffer_size - bitmap_size; 791 - ALIGN_BUFFER(cache_buf, cache_size, 2); 805 + ALIGN_BUFFER(cache_buf, cache_size, sizeof(ucschar_t)); 792 806 memset(pf->buffer_start, 0, bitmap_size); 793 807 /* Initialise cache */ 794 808 font_cache_create(&pf->cache, cache_buf, cache_size, bitmap_size); ··· 797 811 /* 798 812 * Returns width of character 799 813 */ 800 - int font_get_width(struct font* pf, unsigned short char_code) 814 + int font_get_width(struct font* pf, ucschar_t char_code) 801 815 { 802 816 int width; 803 817 struct font_cache_entry *e; ··· 820 834 return width; 821 835 } 822 836 823 - const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) 837 + const unsigned char* font_get_bits(struct font* pf, ucschar_t char_code) 824 838 { 825 839 const unsigned char* bits; 826 840 ··· 831 845 832 846 if (pf->fd >= 0 && pf != &sysfont) 833 847 { 834 - bits = 848 + bits = 835 849 (unsigned char*)font_cache_get(&pf->cache, char_code, 836 850 false, load_cache_entry, pf)->bitmap; 837 851 } ··· 884 898 { 885 899 struct font_cache_entry* p = data; 886 900 struct font* pf = cache_pf; 887 - unsigned short ch; 901 + ucschar_t ch; 888 902 static int buffer_pos = 0; 889 903 #define WRITE_BUFFER 256 890 904 static unsigned char buffer[WRITE_BUFFER]; ··· 899 913 } 900 914 if ( p->_char_code == 0xffff ) 901 915 return; 902 - 916 + 903 917 ch = p->_char_code + pf->firstchar; 904 - buffer[buffer_pos] = ch >> 8; 918 + #ifdef UNICODE32 919 + buffer[buffer_pos] = (ch >> 24) & 0xff; 920 + buffer[buffer_pos+1] = (ch >> 16) & 0xff; 921 + buffer[buffer_pos+2] = (ch >> 8) & 0xff; 922 + buffer[buffer_pos+3] = ch & 0xff; 923 + buffer_pos += 4; 924 + #else 925 + buffer[buffer_pos] = (ch >> 8) & 0xff; 905 926 buffer[buffer_pos+1] = ch & 0xff; 906 927 buffer_pos += 2; 928 + #endif 907 929 return; 908 930 } 909 931 ··· 928 950 fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); 929 951 if (fd >= 0) 930 952 { 953 + uint32_t header = FC_HEADER_VAL; 954 + write(fd, &header, sizeof(header)); 931 955 cache_pf = pf; 932 956 cache_fd = fd; 933 957 lru_traverse(&cache_pf->cache._lru, glyph_file_write); 934 958 glyph_file_write(NULL); 935 - if (cache_fd >= 0) 959 + if (cache_fd >= 0) 936 960 { 937 961 close(cache_fd); 938 962 cache_fd = -1; ··· 944 968 } 945 969 946 970 947 - static int ushortcmp(const void *a, const void *b) 971 + static int ucscharcmp(const void *a, const void *b) 948 972 { 949 - return ((int)(*(unsigned short*)a - *(unsigned short*)b)); 973 + return ((int)(*(ucschar_t*)a - *(ucschar_t*)b)); 950 974 } 951 975 952 976 static NO_INLINE void glyph_cache_load(const char *font_path, struct font *pf) ··· 954 978 #define MAX_SORT 256 955 979 if (pf->fd >= 0) { 956 980 int i, size, fd; 957 - unsigned char tmp[2]; 958 - unsigned short ch; 959 - unsigned short glyphs[MAX_SORT]; 960 - unsigned short glyphs_lru_order[MAX_SORT]; 961 - int glyph_file_skip=0, glyph_file_size=0; 962 - 963 - int sort_size = pf->cache._capacity; 981 + unsigned char tmp[sizeof(ucschar_t)]; 982 + ucschar_t ch; 983 + ucschar_t glyphs[MAX_SORT]; 984 + ucschar_t glyphs_lru_order[MAX_SORT]; 985 + unsigned int glyph_file_skip=0, glyph_file_size=0; 986 + 987 + int sort_size = pf->cache._capacity; 964 988 if ( sort_size > MAX_SORT ) 965 989 sort_size = MAX_SORT; 966 990 ··· 974 998 fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY); 975 999 #endif 976 1000 if (fd >= 0) { 1001 + /* Header */ 1002 + uint32_t hdr = 0; 1003 + read(fd, &hdr, sizeof(hdr)); 1004 + if (hdr != FC_HEADER_VAL) 1005 + goto latin; 977 1006 /* only read what fits */ 978 1007 glyph_file_size = filesize( fd ); 979 - if ( glyph_file_size > 2*pf->cache._capacity ) { 980 - glyph_file_skip = glyph_file_size - 2*pf->cache._capacity; 981 - lseek( fd, glyph_file_skip, SEEK_SET ); 1008 + if (glyph_file_size < sizeof(uint32_t)) 1009 + goto latin; 1010 + glyph_file_size -= sizeof(uint32_t); 1011 + if ( glyph_file_size > (int)sizeof(ucschar_t)*pf->cache._capacity ) { 1012 + glyph_file_skip = glyph_file_size - sizeof(ucschar_t)*pf->cache._capacity; 1013 + lseek( fd, glyph_file_skip + sizeof(uint32_t), SEEK_SET ); 982 1014 } 983 - 984 1015 while(1) { 985 - 986 1016 for ( size = 0; 987 - read( fd, tmp, 2 ) == 2 && size < sort_size; 988 - size++ ) 1017 + read( fd, tmp, sizeof(tmp) ) == sizeof(tmp) && size < sort_size; 1018 + size++ ) 989 1019 { 1020 + #ifdef UNICODE32 1021 + glyphs[size] = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3]; 1022 + #else 990 1023 glyphs[size] = (tmp[0] << 8) | tmp[1]; 1024 + #endif 991 1025 glyphs_lru_order[size] = glyphs[size]; 992 1026 } 993 - 1027 + 994 1028 /* sort glyphs array to make sector cache happy */ 995 - qsort((void *)glyphs, size, sizeof(unsigned short), 996 - ushortcmp ); 1029 + qsort((void *)glyphs, size, sizeof(ucschar_t), 1030 + ucscharcmp ); 997 1031 998 1032 /* load font bitmaps */ 999 1033 for( i = 0; i < size ; i++ ) 1000 - font_get_bits(pf, glyphs[i]); 1001 - 1034 + font_get_bits(pf, glyphs[i]); 1035 + 1002 1036 /* redo to fix lru order */ 1003 1037 for ( i = 0; i < size ; i++) 1004 1038 font_get_bits(pf, glyphs_lru_order[i]); ··· 1009 1043 1010 1044 close(fd); 1011 1045 } else { 1046 + latin: 1012 1047 /* load latin1 chars into cache */ 1013 1048 for ( ch = 32 ; ch < 256 && ch < pf->cache._capacity + 32; ch++ ) 1014 1049 font_get_bits(pf, ch); ··· 1040 1075 /* 1041 1076 * Returns width of character 1042 1077 */ 1043 - int font_get_width(struct font* pf, unsigned short char_code) 1078 + int font_get_width(struct font* pf, ucschar_t char_code) 1044 1079 { 1045 1080 /* check input range*/ 1046 1081 if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size) ··· 1050 1085 return pf->width? pf->width[char_code]: pf->maxwidth; 1051 1086 } 1052 1087 1053 - const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) 1088 + const unsigned char* font_get_bits(struct font* pf, ucschar_t char_code) 1054 1089 { 1055 1090 const unsigned char* bits; 1056 1091 ··· 1079 1114 { 1080 1115 struct font* pf = font_get(fontnum); 1081 1116 font_lock( fontnum, true ); 1082 - unsigned short ch; 1117 + ucschar_t ch; 1083 1118 int width = 0; 1084 1119 size_t b = maxbytes - 1; 1085 1120
+19 -14
firmware/font_cache.c
··· 43 43 int font_cache_entry_size = 44 44 sizeof(struct font_cache_entry) + bitmap_bytes_size; 45 45 46 - /* make sure font cache entries are a multiple of 16 bits */ 47 - if (font_cache_entry_size % 2 != 0) 46 + /* make sure font cache entries are a multiple of sizeof(ucschar_t) */ 47 + while (font_cache_entry_size & (sizeof(ucschar_t) -1)) 48 48 font_cache_entry_size++; 49 49 50 50 int cache_size = buf_size / 51 51 (font_cache_entry_size + LRU_SLOT_OVERHEAD + sizeof(short)); 52 + 53 + #ifdef UNICODE32 54 + /* Ensure LRU index size is a multiple of 32 bits */ 55 + cache_size &= ~1; 56 + #endif 52 57 53 58 fcache->_size = 1; 54 59 fcache->_capacity = cache_size; ··· 72 77 73 78 /************************************************************************* 74 79 * Binary search that attempts a primary lucky guess that succeeds 75 - * when there are consecutive codes in the cache between previous 76 - * search and new search. Returns a negative of insertion point if 80 + * when there are consecutive codes in the cache between previous 81 + * search and new search. Returns a negative of insertion point if 77 82 * not found. 78 83 ************************************************************************/ 79 84 static int search(struct font_cache* fcache, 80 - unsigned short char_code, 85 + ucschar_t char_code, 81 86 int size, 82 87 int *p_insertion_point ) 83 88 { ··· 85 90 int left, right, mid=-1, c; 86 91 left = 0; 87 92 right = size; 88 - 93 + 89 94 /* go for a lucky guess */ 90 - mid = char_code + 95 + mid = char_code + 91 96 fcache->_prev_result - fcache->_prev_char_code; 92 - 93 - /* check bounds */ 97 + 98 + /* check bounds */ 94 99 if ( mid < 0 || mid > right ) 95 100 mid = ( left + right ) / 2; 96 101 ··· 114 119 mid = (left + right) / 2; 115 120 } 116 121 while (left <= right); 117 - 122 + 118 123 /* not found */ 119 124 *p_insertion_point = mid; 120 125 return 0; ··· 124 129 ******************************************************************************/ 125 130 struct font_cache_entry* font_cache_get( 126 131 struct font_cache* fcache, 127 - unsigned short char_code, 132 + ucschar_t char_code, 128 133 bool cache_only, 129 134 void (*callback) (struct font_cache_entry* p, void *callback_data), 130 135 void *callback_data) ··· 132 137 struct font_cache_entry* p; 133 138 int insertion_point; 134 139 int index_to_replace; 135 - 140 + 136 141 /* check bounds */ 137 142 p = lru_data(&fcache->_lru, fcache->_index[0]); 138 143 if( char_code < p->_char_code ) ··· 158 163 } 159 164 else 160 165 { 161 - p = lru_data(&fcache->_lru, 166 + p = lru_data(&fcache->_lru, 162 167 fcache->_index[insertion_point+1]); 163 168 if ( char_code > p->_char_code ) 164 169 insertion_point++; 165 170 } 166 171 } 167 172 } 168 - 173 + 169 174 /* not found */ 170 175 if (cache_only) 171 176 return NULL;
+3 -3
firmware/hangul.c
··· 18 18 * KIND, either express or implied. 19 19 * 20 20 ****************************************************************************/ 21 + #include "config.h" 21 22 #include "hangul.h" 22 23 23 24 const char jamo_table[51][3] = { ··· 75 76 }; 76 77 77 78 /* takes three jamo chars and joins them into one hangul */ 78 - unsigned short hangul_join(unsigned short lead, unsigned short vowel, 79 - unsigned short tail) 79 + ucschar_t hangul_join(ucschar_t lead, ucschar_t vowel, ucschar_t tail) 80 80 { 81 - unsigned short ch = 0xfffd; 81 + ucschar_t ch = 0xfffd; 82 82 83 83 if (lead < 0x3131 || lead > 0x3163) 84 84 return ch;
+1 -1
firmware/include/diacritic.h
··· 27 27 * Sets is_rtl (if it's not NULL) to whether the character 28 28 * belongs to an RTL language. 29 29 */ 30 - bool is_diacritic(const unsigned short char_code, bool *is_rtl); 30 + bool is_diacritic(const ucschar_t char_code, bool *is_rtl); 31 31 32 32 /* Note IS_DIACRITIC macros may elide the function call 33 33 * therefore there is a separate _RTL version that requires a bool pointer
+7 -6
firmware/include/font_cache.h
··· 21 21 #ifndef _FONT_CACHE_H_ 22 22 #define _FONT_CACHE_H_ 23 23 #include <stdbool.h> 24 + #include "config.h" 24 25 #include "lru.h" 25 26 26 27 /******************************************************************************* 27 - * 28 + * 28 29 ******************************************************************************/ 29 30 struct font_cache 30 31 { 31 32 struct lru _lru; 32 - int _size; 33 - int _capacity; 34 - int _prev_char_code; 33 + unsigned int _size; 34 + unsigned int _capacity; 35 + ucschar_t _prev_char_code; 35 36 int _prev_result; 36 37 short *_index; /* index of lru handles in char_code order */ 37 38 }; 38 39 39 40 struct font_cache_entry 40 41 { 41 - unsigned short _char_code; 42 + ucschar_t _char_code; 42 43 unsigned char width; 43 44 unsigned char bitmap[1]; /* place holder */ 44 45 }; ··· 55 56 * Note: With cache_only this can return NULL, which otherwise never happens */ 56 57 struct font_cache_entry* font_cache_get( 57 58 struct font_cache* fcache, 58 - unsigned short char_code, 59 + ucschar_t char_code, 59 60 bool cache_only, 60 61 void (*callback) (struct font_cache_entry* p, void *callback_data), 61 62 void *callback_data);
+1 -1
firmware/include/lru.h
··· 33 33 void *_base; 34 34 }; 35 35 36 + /* LRU_SLOT_OVERHEAD is the fixed portion of struct lru_node */ 36 37 #define LRU_SLOT_OVERHEAD (2 * sizeof(short)) 37 38 38 39 /* Create LRU list with specified size from buf. */ ··· 45 46 void lru_traverse(struct lru* pl, void (*callback)(void* data)); 46 47 47 48 #endif /* LRU_H */ 48 -
+3 -2
firmware/include/rbunicode.h
··· 27 27 */ 28 28 #ifndef _RBUNICODE_H_ 29 29 #define _RBUNICODE_H_ 30 - 30 + 31 31 #include "config.h" 32 32 #include <stdbool.h> 33 33 ··· 63 63 unsigned char* utf16BEdecode(const unsigned char *utf16, unsigned char *utf8, int count); 64 64 unsigned char* utf16decode(const unsigned char *utf16, unsigned char *utf8, int count, int utf8_size, bool le); 65 65 bool utf16_has_bom(const unsigned char *utf16, bool *le); 66 + unsigned long utf16len_utf8(const unsigned char *utf8); 66 67 unsigned long utf8length(const unsigned char *utf8); 67 - const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs); 68 + const unsigned char* utf8decode(const unsigned char *utf8, ucschar_t *ucs); 68 69 void set_codepage(int cp); 69 70 int get_codepage(void); 70 71 int utf8seek(const unsigned char* utf8, int offset);
+88 -53
firmware/target/hosted/filesystem-win32.c
··· 63 63 static HANDLE win32_open(const char *ospath); 64 64 static int win32_stat(const char *ospath, LPBY_HANDLE_FILE_INFORMATION lpInfo); 65 65 66 - unsigned short * strcpy_utf8ucs2(unsigned short *buffer, 67 - const unsigned char *utf8) 66 + static unsigned short * strcpy_utf8utf16(unsigned short *buffer, 67 + const unsigned char *utf8) 68 68 { 69 - for (wchar_t *ucs2 = buffer; 70 - ((utf8 = utf8decode(utf8, ucs2)), *ucs2); ucs2++); 69 + for (wchar_t *ucs = buffer; *ucs ; ucs++) { 70 + ucschar_t cp; 71 + utf8 = utf8decode(utf8, &cp); 72 + #ifdef UNICODE32 73 + if (cp > 0x10000) { 74 + cp -= 0x10000; 75 + *ucs++ = 0xd800 | (cp >> 10); 76 + cp = 0xdc00 | (cp & 0x3ff); 77 + } 78 + #endif 79 + *ucs = cp; 80 + } 71 81 return buffer; 72 82 } 73 83 74 - #if 0 75 - unsigned char * strcpy_ucs2utf8(unsigned char *buffer, 76 - const unsigned short *ucs2) 84 + #if 0 /* Unused in current code */ 85 + static unsigned char * strcpy_utf16utf8(unsigned char *buffer, 86 + const unsigned short *utf16buf) 77 87 { 78 - for (unsigned char *utf8 = buffer; 79 - ((utf8 = utf8encode(*ucs2, utf8)), *ucs2); ucs2++); 80 - return buffer; 81 - } 88 + unsigned char *utf8 = buffer; 82 89 83 - size_t strlen_utf8ucs2(const unsigned char *utf8) 84 - { 85 - /* This won't properly count multiword ucs2 so use the alternative 86 - below for now which doesn't either */ 87 - size_t length = 0; 88 - unsigned short ucschar[2]; 89 - for (unsigned char c = *utf8; c; 90 - ((utf8 = utf8decode(utf8, ucschar)), c = *utf8)) 91 - length++; 90 + /* windows is always LE */ 91 + const int le = 1; 92 92 93 - return length; 93 + while (*utf16buf) { 94 + const unsigned char *utf16 = (const unsigned char *)utf16buf; 95 + unsigned long ucs; 96 + /* Check for a surrogate pair */ 97 + if (*(utf16 + le) >= 0xD8 && *(utf16 + le) < 0xE0) { 98 + ucs = 0x10000 + ((utf16[1 - le] << 10) | ((utf16[le] - 0xD8) << 18) 99 + | utf16[2 + (1 - le)] | ((utf16[2 + le] - 0xDC) << 8)); 100 + utf16buf += 2; 101 + } else { 102 + ucs = utf16[le] << 8 | utf16[1 - le]; 103 + utf16buf++; 104 + } 105 + utf8 = utf8encode(ucs, utf8); 106 + } 107 + return buffer; 94 108 } 95 - #endif /* 0 */ 96 - 97 - size_t strlen_utf8ucs2(const unsigned char *utf8) 98 - { 99 - return utf8length(utf8); 100 - } 101 - 102 - size_t strlen_ucs2utf8(const unsigned short *ucs2) 109 + static size_t strlen_utf16utf8(const unsigned short *utf16buf) 103 110 { 104 111 size_t length = 0; 105 112 unsigned char utf8char[4]; 106 113 107 - for (unsigned short c = *ucs2; c; (c = *++ucs2)) 108 - length += utf8encode(c, utf8char) - utf8char; 114 + /* windows is always LE */ 115 + const int le = 1; 109 116 117 + while (*utf16buf) { 118 + const unsigned char *utf16 = (const unsigned char *)utf16buf; 119 + unsigned long ucs; 120 + /* Check for a surrogate pair */ 121 + if (*(utf16 + le) >= 0xD8 && *(utf16 + le) < 0xE0) { 122 + ucs = 0x10000 + ((utf16[1 - le] << 10) | ((utf16[le] - 0xD8) << 18) 123 + | utf16[2 + (1 - le)] | ((utf16[2 + le] - 0xDC) << 8)); 124 + utf16buf += 2; 125 + } else { 126 + ucs = utf16[le] << 8 | utf16[1 - le]; 127 + utf16buf++; 128 + } 129 + length += utf8encode(ucs, utf8char) - utf8char; 130 + } 110 131 return length; 111 132 } 133 + #endif 112 134 113 - size_t strlcpy_ucs2utf8(char *buffer, const unsigned short *ucs2, 114 - size_t bufsize) 135 + /* Note: Must be exported */ 136 + size_t strlcpy_utf16utf8(char *buffer, const unsigned short *utf16, 137 + size_t bufsize) 115 138 { 116 139 if (!buffer) 117 140 bufsize = 0; ··· 119 142 size_t length = 0; 120 143 unsigned char utf8char[4]; 121 144 122 - for (unsigned short c = *ucs2; c; (c = *++ucs2)) 145 + unsigned long ucc; 146 + while(*utf16) 123 147 { 148 + /* Check for a surrogate UTF16 pair */ 149 + if (*utf16 >= 0xd800 && *utf16 < 0xdc00 && 150 + *(utf16+1) >= 0xdc00 && *(utf16+1) < 0xe000) { 151 + ucc = 0x10000 + (((*utf16 & 0x3ff) << 10) | (*(utf16+1) & 0x3ff)); 152 + utf16++; 153 + } else { 154 + ucc = *utf16; 155 + } 156 + 124 157 /* If the last character won't fit, this won't split it */ 125 - size_t utf8size = utf8encode(c, utf8char) - utf8char; 158 + size_t utf8size = utf8encode(ucc, utf8char) - utf8char; 126 159 if ((length += utf8size) < bufsize) 127 160 buffer = mempcpy(buffer, utf8char, utf8size); 161 + 162 + utf16++; 128 163 } 129 164 130 165 /* Above won't ever copy to very end */ ··· 134 169 return length; 135 170 } 136 171 137 - #define _toucs2(utf8) \ 172 + #define _toutf16(utf8) \ 138 173 ({ const char *_utf8 = (utf8); \ 139 - size_t _l = strlen_utf8ucs2(_utf8); \ 174 + size_t _l = utf16len_utf8(_utf8); \ 140 175 void *_buffer = alloca((_l + 1)*2); \ 141 - strcpy_utf8ucs2(_buffer, _utf8); }) 176 + strcpy_utf8utf16(_buffer, _utf8); }) 142 177 143 - #define _toutf8(ucs2) \ 144 - ({ const char *_ucs2 = (ucs2); \ 145 - size_t _l = strlen_ucs2utf8(_ucs2); \ 178 + #define _toutf8(utf16) \ 179 + ({ const char *_ucs = (utf16); \ 180 + size_t _l = strlen_utf16utf8(_ucs); \ 146 181 void *_buffer = alloca(_l + 1); \ 147 - strcpy_ucs2utf8(_buffer, _ucs2); }) 182 + strcpy_utf16utf8(_buffer, _ucs); }) 148 183 149 184 int os_open(const char *ospath, int oflag, ...) 150 185 { 151 - return _wopen(_toucs2(ospath), oflag __OPEN_MODE_ARG); 186 + return _wopen(_toutf16(ospath), oflag __OPEN_MODE_ARG); 152 187 } 153 188 154 189 int os_creat(const char *ospath, mode_t mode) 155 190 { 156 - return _wcreat(_toucs2(ospath), mode); 191 + return _wcreat(_toutf16(ospath), mode); 157 192 } 158 193 159 194 int os_stat(const char *ospath, struct _stat *s) 160 195 { 161 - return _wstat(_toucs2(ospath), s); 196 + return _wstat(_toutf16(ospath), s); 162 197 } 163 198 164 199 int os_remove(const char *ospath) 165 200 { 166 - return _wremove(_toucs2(ospath)); 201 + return _wremove(_toutf16(ospath)); 167 202 } 168 203 169 204 int os_rename(const char *osold, const char *osnew) 170 205 { 171 206 int errnum = errno; 172 207 173 - const wchar_t *wchosold = _toucs2(osold); 174 - const wchar_t *wchosnew = _toucs2(osnew); 208 + const wchar_t *wchosold = _toutf16(osold); 209 + const wchar_t *wchosnew = _toutf16(osnew); 175 210 176 211 int rc = _wrename(wchosold, wchosnew); 177 212 if (rc < 0 && errno == EEXIST) ··· 213 248 214 249 _WDIR * os_opendir(const char *osdirname) 215 250 { 216 - return _wopendir(_toucs2(osdirname)); 251 + return _wopendir(_toutf16(osdirname)); 217 252 } 218 253 219 254 int os_mkdir(const char *ospath, mode_t mode) 220 255 { 221 - return _wmkdir(_toucs2(ospath)); 256 + return _wmkdir(_toutf16(ospath)); 222 257 (void)mode; 223 258 } 224 259 225 260 int os_rmdir(const char *ospath) 226 261 { 227 - return _wrmdir(_toucs2(ospath)); 262 + return _wrmdir(_toutf16(ospath)); 228 263 } 229 264 230 265 int os_dirfd(_WDIR *osdirp) ··· 288 323 { 289 324 /* FILE_FLAG_BACKUP_SEMANTICS is required for this to succeed at opening 290 325 a directory */ 291 - HANDLE h = CreateFileW(_toucs2(ospath), GENERIC_READ, 326 + HANDLE h = CreateFileW(_toutf16(ospath), GENERIC_READ, 292 327 FILE_SHARE_READ | FILE_SHARE_WRITE | 293 328 FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 294 329 FILE_FLAG_BACKUP_SEMANTICS, NULL); ··· 479 514 480 515 char volpath[MAX_PATH]; 481 516 if (os_volume_path(IF_MV(volume, ) volpath, sizeof (volpath)) >= 0) 482 - GetDiskFreeSpaceExW(_toucs2(volpath), &free, &size, NULL); 517 + GetDiskFreeSpaceExW(_toutf16(volpath), &free, &size, NULL); 483 518 484 519 if (sizep) 485 520 *sizep = size.QuadPart / 1024;
+3 -3
firmware/target/hosted/filesystem-win32.h
··· 27 27 /* filesystem-win32.c contains some string functions that could be useful 28 28 * elsewhere; just move them away to unicode.c or something if they prove 29 29 * so. */ 30 - size_t strlcpy_ucs2utf8(char *buffer, const unsigned short *ucs, 31 - size_t bufsize); 30 + size_t strlcpy_utf16utf8(char *buffer, const unsigned short *utf16, 31 + size_t bufsize); 32 32 33 - #define strlcpy_from_os strlcpy_ucs2utf8 33 + #define strlcpy_from_os strlcpy_utf16utf8 34 34 #endif /* __MINGW32__ */ 35 35 36 36 #endif /* !OSFUNCTIONS_DECLARED */
+2 -2
lib/rbcodec/metadata/id3tags.c
··· 1092 1092 1093 1093 if (!parse_as_utf8(tag, &bytesread)) 1094 1094 { 1095 - /* UTF-8 could potentially be 3 times larger */ 1095 + /* UTF-8 could potentially be 4 times larger */ 1096 1096 /* so we need to create a new buffer */ 1097 - int utf8_size = (3 * bytesread); 1097 + int utf8_size = (4 * bytesread); 1098 1098 if (utf8_size > ID3V2_BUF_SIZE) 1099 1099 { 1100 1100 //limit stack allocation to avoid stack overflow
+2 -2
tools/convbdf.c
··· 116 116 int gen_fnt = 0; 117 117 int gen_map = 1; 118 118 int start_char = 0; 119 - int limit_char = 65535; 119 + int limit_char = 0x10FFFF; 120 120 int oflag = 0; 121 121 char outfile[256]; 122 122 ··· 569 569 int bdf_read_header(FILE *fp, struct font* pf) 570 570 { 571 571 int encoding; 572 - int firstchar = 65535; 572 + int firstchar = 0x10FFFF; 573 573 int lastchar = -1; 574 574 char buf[256]; 575 575 char facename[256];
+1 -1
tools/convttf.c
··· 91 91 static FT_UShort nocmap; 92 92 93 93 int pct = 0; /* display ttc table if it is not zero. */ 94 - FT_Long max_char = 65535; 94 + FT_Long max_char = 0x10FFFF; 95 95 int pixel_size = 15; 96 96 FT_Long start_char = 0; 97 97 FT_Long limit_char;