diff --git a/Makefile.config.in b/Makefile.config.in index f5145e9c..2282dfc2 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -155,6 +155,7 @@ CONFIG_SPIDERMONKEY = @CONFIG_SPIDERMONKEY@ CONFIG_SSL = @CONFIG_SSL@ CONFIG_SYSMOUSE = @CONFIG_SYSMOUSE@ CONFIG_URI_REWRITE = @CONFIG_URI_REWRITE@ +CONFIG_UTF_8 = @CONFIG_UTF_8@ CONFIG_XBEL_BOOKMARKS = @CONFIG_XBEL_BOOKMARKS@ CONFIG_XMLTO = @CONFIG_XMLTO@ diff --git a/configure.in b/configure.in index b87f00a7..6e95ac71 100644 --- a/configure.in +++ b/configure.in @@ -1257,6 +1257,10 @@ EL_ARG_ENABLE(CONFIG_OWN_LIBC, own-libc, [Own libc stubs], EL_ARG_ENABLE(CONFIG_SMALL, small, [Small binary], [ --enable-small reduce binary size as far as possible (but see the bottom of doc/small.txt!)]) +EL_ARG_ENABLE(CONFIG_UTF_8, utf-8, [UTF-8], + [ --enable-utf-8 enable UTF-8 support]) + + AC_ARG_ENABLE(weehoofooboomookerchoo, [ Also check out the features.conf file for more information about features! diff --git a/src/bfu/button.c b/src/bfu/button.c index 5c1ff8a4..8cccbc39 100644 --- a/src/bfu/button.c +++ b/src/bfu/button.c @@ -167,6 +167,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data) attr = get_opt_bool("ui.dialogs.underline_button_shortcuts") ? SCREEN_ATTR_UNDERLINE : 0; +#ifdef CONFIG_UTF_8 if (term->utf8) { unsigned char *text2 = text; unsigned char *end = text @@ -192,6 +193,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data) } len = x1 - !!hk_state; } else +#endif /* CONFIG_UTF_8 */ if (hk_pos >= 0) { int right = widget_data->widget->info.button.truetextlen - hk_pos - 1; diff --git a/src/bfu/dialog.c b/src/bfu/dialog.c index 554b9dbc..e585ac57 100644 --- a/src/bfu/dialog.c +++ b/src/bfu/dialog.c @@ -97,18 +97,25 @@ redraw_dialog(struct dialog_data *dlg_data, int layout) title_color = get_bfu_color(term, "dialog.title"); if (title_color && box.width > 2) { unsigned char *title = dlg_data->dlg->title; +#ifdef CONFIG_UTF_8 unsigned char *t2 = title; int titlelen = strlen(title); int len = term->utf8 ? strlen_utf8(&t2) : titlelen; -#if 1 len = int_min(box.width - 2, len); -#endif int x = (box.width - len) / 2 + box.x; +#else + int titlelen = int_min(box.width - 2, strlen(title)); + int x = (box.width - titlelen) / 2 + box.x; +#endif /* CONFIG_UTF_8 */ int y = box.y - 1; draw_text(term, x - 1, y, " ", 1, 0, title_color); draw_text(term, x, y, title, titlelen, 0, title_color); +#ifdef CONFIG_UTF_8 draw_text(term, x + len, y, " ", 1, 0, title_color); +#else + draw_text(term, x + titlelen, y, " ", 1, 0, title_color); +#endif /* CONFIG_UTF_8 */ } } diff --git a/src/bfu/inpfield.c b/src/bfu/inpfield.c index 84874888..e907119d 100644 --- a/src/bfu/inpfield.c +++ b/src/bfu/inpfield.c @@ -266,8 +266,11 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data, struct terminal *term = dlg_data->win->term; struct color_pair *color; int sel = is_selected_widget(dlg_data, widget_data); +#ifdef CONFIG_UTF_8 int len = 0, left = 0; +#endif /* CONFIG_UTF_8 */ +#ifdef CONFIG_UTF_8 if (term->utf8) { unsigned char *t = widget_data->cdata; unsigned char *t2 = t; @@ -284,7 +287,9 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data, } t[p] = tmp; widget_data->info.field.vpos = (int)(t2 - t); - } else { + } else +#endif /* CONFIG_UTF_8 */ + { int_bounds(&widget_data->info.field.vpos, widget_data->info.field.cpos - widget_data->box.width + 1, widget_data->info.field.cpos); @@ -298,26 +303,34 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data, color = get_bfu_color(term, "dialog.field-text"); if (color) { unsigned char *text = widget_data->cdata + widget_data->info.field.vpos; +#ifdef CONFIG_UTF_8 unsigned char *text2 = text; - int x, l, len, w; +#endif /* CONFIG_UTF_8 */ + int len, w; - len = (term->utf8) ? strlen_utf8(&text2) : strlen(text); +#ifdef CONFIG_UTF_8 + if (term->utf8) + len = strlen_utf8(&text2); + else +#endif /* CONFIG_UTF_8 */ + len = strlen(text); w = int_min(len, widget_data->box.width); if (!hide) { +#ifdef CONFIG_UTF_8 + int x; if (term->utf8) { + int l; for (l = 0, x = 0; x < w; x++) l += utf8charlen(text+l); w = l; } +#endif /* CONFIG_UTF_8 */ draw_text(term, widget_data->box.x, widget_data->box.y, text, w, 0, color); } else { struct box box; - if (term->utf8) len = strlen_utf8(&text); - w = int_min(len, widget_data->box.width); - copy_box(&box, &widget_data->box); box.width = w; @@ -328,12 +341,13 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data, if (sel) { int x; - if (term->utf8) { +#ifdef CONFIG_UTF_8 + if (term->utf8) x = widget_data->box.x + len - left; - } else { + else +#endif /* CONFIG_UTF_8 */ x = widget_data->box.x + widget_data->info.field.cpos - widget_data->info.field.vpos; - } set_cursor(term, x, widget_data->box.y, 0); set_window_ptr(dlg_data->win, widget_data->box.x, widget_data->box.y); } @@ -473,6 +487,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) case ACT_EDIT_RIGHT: if (widget_data->info.field.cpos < strlen(widget_data->cdata)) { +#ifdef CONFIG_UTF_8 if (term->utf8) { unsigned char *next = widget_data->cdata + widget_data->info.field.cpos; unsigned char *end = strchr(next, '\0'); @@ -480,13 +495,17 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) utf_8_to_unicode(&next, end); widget_data->info.field.cpos = (int)(next - widget_data->cdata); } else +#endif /* CONFIG_UTF_8 */ + { widget_data->info.field.cpos++; + } } goto display_field; case ACT_EDIT_LEFT: if (widget_data->info.field.cpos > 0) widget_data->info.field.cpos--; +#ifdef CONFIG_UTF_8 if (widget_data->info.field.cpos && term->utf8) { unsigned char *t = widget_data->cdata; unsigned char *t2 = t; @@ -499,6 +518,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) widget_data->info.field.cpos = (int)(t2 - t); } +#endif /* CONFIG_UTF_8 */ goto display_field; case ACT_EDIT_HOME: @@ -510,6 +530,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) goto display_field; case ACT_EDIT_BACKSPACE: +#ifdef CONFIG_UTF_8 if (widget_data->info.field.cpos && term->utf8) { unsigned char *t = widget_data->cdata; unsigned char *t2 = t; @@ -523,6 +544,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) widget_data->info.field.cpos = (int)(t2 - t); goto display_field; } +#endif /* CONFIG_UTF_8 */ if (widget_data->info.field.cpos) { memmove(widget_data->cdata + widget_data->info.field.cpos - 1, widget_data->cdata + widget_data->info.field.cpos, @@ -537,6 +559,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) if (widget_data->info.field.cpos >= cdata_len) goto display_field; +#ifdef CONFIG_UTF_8 if (term->utf8) { unsigned char *next = widget_data->cdata + widget_data->info.field.cpos; unsigned char *dest = next; @@ -546,6 +569,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) memmove(dest, next, strlen(next) + 1); goto display_field; } +#endif /* CONFIG_UTF_8 */ memmove(widget_data->cdata + widget_data->info.field.cpos, widget_data->cdata + widget_data->info.field.cpos + 1, cdata_len - widget_data->info.field.cpos + 1); @@ -627,6 +651,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) memmove(text + 1, text, textlen + 1); *text = get_kbd_key(ev); +#ifdef CONFIG_UTF_8 if (term->utf8) { static unsigned char buf[7]; unsigned char *t = buf; @@ -641,6 +666,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data) return EVENT_PROCESSED; else i = 0; } +#endif /* CONFIG_UTF_8 */ goto display_field; } } diff --git a/src/bfu/menu.c b/src/bfu/menu.c index 0b71a648..addf8575 100644 --- a/src/bfu/menu.c +++ b/src/bfu/menu.c @@ -346,7 +346,6 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text, struct color_pair *hk_color_sel = get_bfu_color(term, "menu.hotkey.selected"); enum screen_char_attr hk_attr = get_opt_bool("ui.dialogs.underline_hotkeys") ? SCREEN_ATTR_UNDERLINE : 0; - unsigned char *text2, *end; unsigned char c; int xbase = x + L_TEXT_SPACE; int w = width - (L_TEXT_SPACE + R_TEXT_SPACE); @@ -368,7 +367,10 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text, hk_color_sel = tmp; } +#ifdef CONFIG_UTF_8 if (term->utf8) goto utf8; +#endif /* CONFIG_UTF_8 */ + for (x = 0; x - !!hk_state < w && (c = text[x]); x++) { if (!hk_state && x == hotkey_pos - 1) { hk_state = 1; @@ -381,13 +383,15 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text, (double_hk ? hk_color_sel : hk_color)); #else draw_char(term, xbase + x - 1, y, c, hk_attr, hk_color); -#endif +#endif /* CONFIG_DEBUG */ hk_state = 2; } else { draw_char(term, xbase + x - !!hk_state, y, c, 0, color); } } return; +#ifdef CONFIG_UTF_8 + unsigned char *text2, *end; utf8: end = strchr(text, '\0'); text2 = text; @@ -405,14 +409,14 @@ utf8: (double_hk ? hk_color_sel : hk_color)); #else draw_char(term, xbase + x - 1, y, data, hk_attr, hk_color); -#endif +#endif /* CONFIG_DEBUG */ hk_state = 2; } else { draw_char(term, xbase + x - !!hk_state, y, data, 0, color); } } - +#endif /* CONFIG_UTF_8 */ } static inline void diff --git a/src/dialogs/options.c b/src/dialogs/options.c index 906bc83f..31b59b4c 100644 --- a/src/dialogs/options.c +++ b/src/dialogs/options.c @@ -59,6 +59,9 @@ charset_list(struct terminal *term, void *xxx, void *ses_) unsigned char *name = get_cp_name(i); if (!name) break; +#ifndef CONFIG_UTF_8 + if (is_cp_special(i)) continue; +#endif /* CONFIG_UTF_8 */ add_to_menu(&mi, name, NULL, ACT_MAIN_NONE, display_codepage, get_cp_mime_name(i), 0); diff --git a/src/document/dom/renderer.c b/src/document/dom/renderer.c index 0461aacb..e70df10f 100644 --- a/src/document/dom/renderer.c +++ b/src/document/dom/renderer.c @@ -250,8 +250,10 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template, struct document *document = renderer->document; struct conv_table *convert = renderer->convert_table; enum convert_string_mode mode = renderer->convert_mode; +#ifdef CONFIG_UTF_8 int utf8 = document->options.utf8; unsigned char *end, *text; +#endif /* CONFIG_UTF_8 */ int x; @@ -268,7 +270,9 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template, add_search_node(renderer, length); +#ifdef CONFIG_UTF_8 if (utf8) goto utf_8; +#endif /* CONFIG_UTF_8 */ for (x = 0; x < length; x++, renderer->canvas_x++) { unsigned char data = string[x]; @@ -297,6 +301,7 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template, copy_screen_chars(POS(renderer), template, 1); } +#ifdef CONFIG_UTF_8 goto end; utf_8: end = string + length; @@ -333,6 +338,7 @@ utf_8: copy_screen_chars(POS(renderer), template, 1); } end: +#endif /* CONFIG_UTF_8 */ mem_free(string); } @@ -1028,7 +1034,9 @@ render_dom_document(struct cache_entry *cached, struct document *document, init_dom_renderer(&renderer, document, buffer, convert_table); document->bgcolor = document->options.default_bg; +#ifdef CONFIG_UTF_8 document->options.utf8 = is_cp_special(document->options.cp); +#endif /* CONFIG_UTF_8 */ if (document->options.plain) parser_type = SGML_PARSER_STREAM; diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c index e9a8a5a4..41a79657 100644 --- a/src/document/html/renderer.c +++ b/src/document/html/renderer.c @@ -403,6 +403,7 @@ get_format_screen_char(struct html_context *html_context, return &schar_cache; } +#ifdef CONFIG_UTF_8 /* First possibly do the format change and then find out what coordinates * to use since sub- or superscript might change them */ static inline int @@ -492,6 +493,48 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen, } return len; } +#else + +/* First possibly do the format change and then find out what coordinates + * to use since sub- or superscript might change them */ +static inline void +set_hline(struct html_context *html_context, unsigned char *chars, int charslen, + enum link_state link_state) +{ + struct part *part = html_context->part; + struct screen_char *schar = get_format_screen_char(html_context, + link_state); + int x = part->cx; + int y = part->cy; + + assert(part); + if_assert_failed return; + + if (realloc_spaces(part, x + charslen)) + return; + + if (part->document) { + if (realloc_line(html_context, part->document, + Y(y), X(x) + charslen - 1)) + return; + + for (; charslen > 0; charslen--, x++, chars++) { + if (*chars == NBSP_CHAR) { + schar->data = ' '; + part->spaces[x] = html_context->options->wrap_nbsp; + } else { + part->spaces[x] = (*chars == ' '); + schar->data = *chars; + } + copy_screen_chars(&POS(x, y), schar, 1); + } + } else { + for (; charslen > 0; charslen--, x++, chars++) { + part->spaces[x] = (*chars == ' '); + } + } +} +#endif /* CONFIG_UTF_8 */ static void move_links(struct html_context *html_context, int xf, int yf, int xt, int yt) @@ -1218,9 +1261,15 @@ done_link_state_info(void) sizeof(renderer_context.link_state_info)); } +#ifdef CONFIG_UTF_8 static inline void process_link(struct html_context *html_context, enum link_state link_state, unsigned char *chars, int charslen, int utf8_len) +#else +static inline void +process_link(struct html_context *html_context, enum link_state link_state, + unsigned char *chars, int charslen) +#endif /* CONFIG_UTF_8 */ { struct part *part = html_context->part; struct link *link; @@ -1272,7 +1321,9 @@ process_link(struct html_context *html_context, enum link_state link_state, if (x_offset) { charslen -= x_offset; chars += x_offset; +#ifdef CONFIG_UTF_8 utf8_len -= x_offset; +#endif /* CONFIG_UTF_8 */ } link = new_link(html_context, chars, charslen); @@ -1287,14 +1338,24 @@ process_link(struct html_context *html_context, enum link_state link_state, } /* Add new canvas positions to the link. */ - if (realloc_points(link, link->npoints + utf8_len)) { +#ifdef CONFIG_UTF_8 + if (realloc_points(link, link->npoints + utf8_len)) +#else + if (realloc_points(link, link->npoints + charslen)) +#endif /* CONFIG_UTF_8 */ + { struct point *point = &link->points[link->npoints]; int x = X(part->cx) + x_offset; int y = Y(part->cy); +#ifdef CONFIG_UTF_8 link->npoints += utf8_len; - for (; utf8_len > 0; utf8_len--, point++, x++) { + for (; utf8_len > 0; utf8_len--, point++, x++) +#else + for (; charslen > 0; charslen--, point++, x++) +#endif /* CONFIG_UTF_8 */ + { point->x = x; point->y = y; } @@ -1346,7 +1407,9 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen) enum link_state link_state; int update_after_subscript = renderer_context.subscript; struct part *part; +#ifdef CONFIG_UTF_8 int utf8_len; +#endif /* CONFIG_UTF_8 */ assert(html_context); if_assert_failed return; @@ -1405,7 +1468,11 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen) else if (html_context->options->links_numbering) put_link_number(html_context); } - utf8_len = set_hline(html_context, chars, charslen, link_state); +#ifdef CONFIG_UTF_8 + utf8_len = +#endif /* CONFIG_UTF_8 */ + set_hline(html_context, chars, charslen, link_state); + if (link_state != LINK_STATE_NONE) { #define is_drawing_subs_or_sups() \ @@ -1425,15 +1492,29 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen) } #undef is_drawing_subs_or_sups + +#ifdef CONFIG_UTF_8 process_link(html_context, link_state, chars, charslen, utf8_len); +#else + process_link(html_context, link_state, chars, charslen); +#endif /* CONFIG_UTF_8 */ } +#ifdef CONFIG_UTF_8 if (renderer_context.nowrap && part->cx + utf8_len > overlap(par_format)) return; part->cx += utf8_len; +#else + if (renderer_context.nowrap + && part->cx + charslen > overlap(par_format)) + return; + + part->cx += charslen; +#endif /* CONFIG_UTF_8 */ + renderer_context.nobreak = 0; if (!(html_context->options->wrap || html_is_preformatted())) { @@ -1449,7 +1530,11 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen) } assert(charslen > 0); +#ifdef CONFIG_UTF_8 part->xa += utf8_len; +#else + part->xa += charslen; +#endif /* CONFIG_UTF_8 */ int_lower_bound(&part->max_width, part->xa + par_format.leftmargin + par_format.rightmargin - (chars[charslen - 1] == ' ' @@ -2013,7 +2098,9 @@ render_html_document(struct cache_entry *cached, struct document *document, &document->cp, &document->cp_status, document->options.hard_assume); +#ifdef CONFIG_UTF_8 html_context->options->utf8 = is_cp_special(document->options.cp); +#endif /* CONFIG_UTF_8 */ if (title.length) { document->title = convert_string(renderer_context.convert_table, diff --git a/src/document/options.h b/src/document/options.h index db510b33..d2a33bfe 100644 --- a/src/document/options.h +++ b/src/document/options.h @@ -71,7 +71,9 @@ struct document_options { unsigned int plain:1; unsigned int wrap:1; +#ifdef CONFIG_UTF_8 unsigned int utf8:1; +#endif /* CONFIG_UTF_8 */ /* XXX: Everything past this comment is specialy handled by compare_opt() */ unsigned char *framename; diff --git a/src/document/plain/renderer.c b/src/document/plain/renderer.c index f19af844..d238efc0 100644 --- a/src/document/plain/renderer.c +++ b/src/document/plain/renderer.c @@ -234,10 +234,12 @@ add_document_line(struct plain_renderer *renderer, struct screen_char *template = &renderer->template; struct screen_char saved_renderer_template = *template; struct screen_char *pos, *startpos; +#ifdef CONFIG_UTF_8 unsigned char *end, *text; + int utf8 = document->options.utf8; +#endif /* CONFIG_UTF_8 */ int lineno = renderer->lineno; int expanded = 0; - int utf8 = document->options.utf8; int width = line_width; int line_pos; @@ -278,7 +280,9 @@ add_document_line(struct plain_renderer *renderer, assert(expanded >= 0); +#ifdef CONFIG_UTF_8 if (utf8) goto utf_8; +#endif /* CONFIG_UTF_8 */ startpos = pos = realloc_line(document, width + expanded, lineno); if (!pos) { mem_free(line); @@ -404,6 +408,7 @@ add_document_line(struct plain_renderer *renderer, *template = saved_renderer_template; } } +#ifdef CONFIG_UTF_8 goto end; utf_8: end = line + width; @@ -537,6 +542,7 @@ utf_8: } } end: +#endif /* CONFIG_UTF_8 */ mem_free(line); realloc_line(document, pos - startpos, lineno); @@ -694,7 +700,9 @@ render_plain_document(struct cache_entry *cached, struct document *document, document->bgcolor = document->options.default_bg; document->width = 0; +#ifdef CONFIG_UTF_8 document->options.utf8 = is_cp_special(document->options.cp); +#endif /* CONFIG_UTF_8 */ /* Setup the style */ init_template(&renderer.template, &document->options); diff --git a/src/intl/charsets.c b/src/intl/charsets.c index cae7b274..9a224399 100644 --- a/src/intl/charsets.c +++ b/src/intl/charsets.c @@ -143,8 +143,10 @@ u2cp_(unicode_val_T u, int to, int no_nbsp_hack) to &= ~SYSTEM_CHARSET_FLAG; +#ifdef CONFIG_UTF_8 if (codepages[to].table == table_utf_8) return encode_utf_8(u); +#endif /* CONFIG_UTF_8 */ /* To mark non breaking spaces, we use a special char NBSP_CHAR. */ if (u == 0xa0) return no_nbsp_hack ? " " : NBSP_CHAR_STRING; @@ -168,25 +170,15 @@ u2cp_(unicode_val_T u, int to, int no_nbsp_hack) return no_str; } - -/* Number of bytes utf8 character indexed by first byte. Illegal bytes are - * equal ones and handled different. */ -static char utf8char_len_tab[256] = -{ - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4, 5,5,5,5,6,6,1,1, -}; - static unsigned char utf_buffer[7]; +#ifdef CONFIG_UTF_8 inline unsigned char * encode_utf_8(unicode_val_T u) +#else +static unsigned char * +encode_utf_8(unicode_val_T u) +#endif /* CONFIG_UTF_8 */ { memset(utf_buffer, 0, 7); @@ -220,6 +212,21 @@ encode_utf_8(unicode_val_T u) return utf_buffer; } +#ifdef CONFIG_UTF_8 +/* Number of bytes utf8 character indexed by first byte. Illegal bytes are + * equal ones and handled different. */ +static char utf8char_len_tab[256] = +{ + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4, 5,5,5,5,6,6,1,1, +}; + inline int utf8charlen(const unsigned char *p) { int len; @@ -297,6 +304,7 @@ utf_8_to_unicode(unsigned char **string, unsigned char *end) *string = str + length; return u > 0xffff ? '*' : u; } +#endif /* CONFIG_UTF_8 */ /* This slow and ugly code is used by the terminal utf_8_io */ unsigned char * @@ -533,10 +541,12 @@ get_entity_string(const unsigned char *str, const int strlen, int encoding) if (strlen <= 0) return NULL; +#ifdef CONFIG_UTF_8 /* TODO: caching UTF-8 */ encoding &= ~SYSTEM_CHARSET_FLAG; if (codepages[encoding].table == table_utf_8) goto skip; +#endif /* CONFIG_UTF_8 */ if (first_time) { memset(&nb_entity_cache, 0, ENTITY_CACHE_MAXLEN * sizeof(unsigned int)); @@ -591,7 +601,9 @@ get_entity_string(const unsigned char *str, const int strlen, int encoding) fprintf(stderr, "miss\n"); #endif } +#ifdef CONFIG_UTF_8 skip: +#endif /* CONFIG_UTF_8 */ if (*str == '#') { /* Numeric entity. */ int l = (int) strlen; unsigned char *st = (unsigned char *) str; @@ -643,9 +655,11 @@ skip: if (element) result = u2cp(element->c, encoding); } +#ifdef CONFIG_UTF_8 if (codepages[encoding].table == table_utf_8) { return result; } +#endif /* CONFIG_UTF_8 */ end: /* Take care of potential buffer overflow. */ if (strlen < sizeof(entity_cache[slen][0].str)) { diff --git a/src/intl/charsets.h b/src/intl/charsets.h index d57913a5..f237e8f9 100644 --- a/src/intl/charsets.h +++ b/src/intl/charsets.h @@ -53,10 +53,12 @@ unsigned char *get_cp_name(int); unsigned char *get_cp_mime_name(int); int is_cp_special(int); void free_conv_table(void); +#ifdef CONFIG_UTF_8 inline unsigned char *encode_utf_8(unicode_val_T); inline int utf8charlen(const unsigned char *); inline int strlen_utf8(unsigned char **); inline unicode_val_T utf_8_to_unicode(unsigned char **, unsigned char *); +#endif /* CONFIG_UTF_8 */ unsigned char *cp2utf_8(int, int); diff --git a/src/terminal/draw.c b/src/terminal/draw.c index b44b8b9c..5f94ab18 100644 --- a/src/terminal/draw.c +++ b/src/terminal/draw.c @@ -103,7 +103,11 @@ draw_char_color(struct terminal *term, int x, int y, struct color_pair *color) } void +#ifdef CONFIG_UTF_8 draw_char_data(struct terminal *term, int x, int y, uint16_t data) +#else +draw_char_data(struct terminal *term, int x, int y, unsigned char data) +#endif /* CONFIG_UTF_8 */ { struct screen_char *screen_char = get_char(term, x, y); @@ -199,10 +203,17 @@ draw_border(struct terminal *term, struct box *box, set_screen_dirty(term->screen, borderbox.y, borderbox.y + borderbox.height); } +#ifdef CONFIG_UTF_8 void draw_char(struct terminal *term, int x, int y, uint16_t data, enum screen_char_attr attr, struct color_pair *color) +#else +void +draw_char(struct terminal *term, int x, int y, + unsigned char data, enum screen_char_attr attr, + struct color_pair *color) +#endif /* CONFIG_UTF_8 */ { struct screen_char *screen_char = get_char(term, x, y); @@ -278,6 +289,7 @@ draw_shadow(struct terminal *term, struct box *box, draw_box(term, &dbox, ' ', 0, color); } +#ifdef CONFIG_UTF_8 static void draw_text_utf8(struct terminal *term, int x, int y, unsigned char *text, int length, @@ -312,6 +324,7 @@ draw_text_utf8(struct terminal *term, int x, int y, set_screen_dirty(term->screen, y, y); } +#endif /* CONFIG_UTF_8 */ void draw_text(struct terminal *term, int x, int y, @@ -324,10 +337,12 @@ draw_text(struct terminal *term, int x, int y, assert(text && length >= 0); if_assert_failed return; +#ifdef CONFIG_UTF_8 if (term->utf8) { draw_text_utf8(term, x, y, text, length, attr, color); return; } +#endif /* CONFIG_UTF_8 */ if (length <= 0) return; pos = get_char(term, x, y); diff --git a/src/terminal/draw.h b/src/terminal/draw.h index 8b1e6f63..4d7307e7 100644 --- a/src/terminal/draw.h +++ b/src/terminal/draw.h @@ -19,7 +19,11 @@ enum screen_char_attr { /* One position in the terminal screen's image. */ struct screen_char { /* Contains either character value or frame data. */ +#ifdef CONFIG_UTF_8 uint16_t data; +#else + unsigned char data; +#endif /* CONFIG_UTF_8 */ /* Attributes are screen_char_attr bits. */ unsigned char attr; @@ -202,7 +206,11 @@ void draw_char_color(struct terminal *term, int x, int y, struct color_pair *color); /* Sets the data of a screen position. */ +#ifdef CONFIG_UTF_8 void draw_char_data(struct terminal *term, int x, int y, uint16_t data); +#else +void draw_char_data(struct terminal *term, int x, int y, unsigned char data); +#endif /* CONFIG_UTF_8 */ /* Sets the data to @border and of a screen position. */ void draw_border_char(struct terminal *term, int x, int y, @@ -213,9 +221,15 @@ void draw_border_cross(struct terminal *, int x, int y, enum border_cross_direction, struct color_pair *color); /* Draws a char. */ +#ifdef CONFIG_UTF_8 void draw_char(struct terminal *term, int x, int y, uint16_t data, enum screen_char_attr attr, struct color_pair *color); +#else +void draw_char(struct terminal *term, int x, int y, + unsigned char data, enum screen_char_attr attr, + struct color_pair *color); +#endif /* CONFIG_UTF_8 */ /* Draws area defined by @box using the same colors and attributes. */ void draw_box(struct terminal *term, struct box *box, diff --git a/src/terminal/event.c b/src/terminal/event.c index 29c61d33..07c32ee0 100644 --- a/src/terminal/event.c +++ b/src/terminal/event.c @@ -245,6 +245,9 @@ handle_interlink_event(struct terminal *term, struct term_event *ev) case EVENT_KBD: { +#ifndef CONFIG_UTF_8 + int utf8_io = -1; +#endif /* CONFIG_UTF_8 */ int key = get_kbd_key(ev); reset_timer(); @@ -259,7 +262,13 @@ handle_interlink_event(struct terminal *term, struct term_event *ev) } if (interlink->utf_8.len) { - if ((key & 0xC0) == 0x80 && term->utf8) { +#ifdef CONFIG_UTF_8 + if ((key & 0xC0) == 0x80 && term->utf8) +#else + utf8_io = get_opt_bool_tree(term->spec, "utf_8_io"); + if ((key & 0xC0) == 0x80 && utf8_io) +#endif /* CONFIG_UTF_8 */ + { interlink->utf_8.ucs <<= 6; interlink->utf_8.ucs |= key & 0x3F; if (! --interlink->utf_8.len) { @@ -277,14 +286,19 @@ handle_interlink_event(struct terminal *term, struct term_event *ev) } } - if (key < 0x80 || key > 0xFF || !term->utf8) { - +#ifdef CONFIG_UTF_8 + if (key < 0x80 || key > 0xFF || !term->utf8) +#else + if (key < 0x80 || key > 0xFF + || (utf8_io == -1 + ? !get_opt_bool_tree(term->spec, "utf_8_io") + : !utf8_io)) +#endif /* CONFIG_UTF_8 */ + { term_send_event(term, ev); break; - } - - else if ((key & 0xC0) == 0xC0 && (key & 0xFE) != 0xFE) { + } else if ((key & 0xC0) == 0xC0 && (key & 0xFE) != 0xFE) { unsigned int mask, cov = 0x80; int len = 0; diff --git a/src/terminal/screen.c b/src/terminal/screen.c index a4ac73ba..dcf86861 100644 --- a/src/terminal/screen.c +++ b/src/terminal/screen.c @@ -30,7 +30,7 @@ unsigned char frame_dumb[48] = " ||||++||++++++--|-+||++--|-+----++++++++ "; static unsigned char frame_vt100[48] = "aaaxuuukkuxkjjjkmvwtqnttmlvwtqnvvwwmmllnnjla "; -#if 0 +#ifndef CONFIG_UTF_8 /* For UTF8 I/O */ static unsigned char frame_vt100_u[48] = { 177, 177, 177, 179, 180, 180, 180, 191, @@ -40,7 +40,7 @@ static unsigned char frame_vt100_u[48] = { 193, 194, 194, 192, 192, 218, 218, 197, 197, 217, 218, 177, 32, 32, 32, 32 }; -#endif +#endif /* CONFIG_UTF_8 */ static unsigned char frame_freebsd[48] = { 130, 138, 128, 153, 150, 150, 150, 140, @@ -80,10 +80,12 @@ static struct string m11_hack_frame_seqs[] = { /* begin border: */ TERM_STRING("\033[11m"), }; +#ifdef CONFIG_UTF_8 static struct string utf8_linux_frame_seqs[] = { /* end border: */ TERM_STRING("\033[10m\033%G"), /* begin border: */ TERM_STRING("\033%@\033[11m"), }; +#endif /* CONFIG_UTF_8 */ static struct string vt100_frame_seqs[] = { /* end border: */ TERM_STRING("\x0f"), @@ -106,6 +108,13 @@ struct screen_driver { * uniquely identify the screen_driver. */ enum term_mode_type type; +#ifndef CONFIG_UTF_8 + /* Charsets when doing UTF8 I/O. */ + /* [0] is the common charset and [1] is the frame charset. + * Test wether to use UTF8 I/O using the use_utf8_io() macro. */ + int charsets[2]; +#endif /* CONFIG_UTF_8 */ + /* The frame translation table. May be NULL. */ unsigned char *frame; @@ -121,8 +130,10 @@ struct screen_driver { /* These are directly derived from the terminal options. */ unsigned int transparent:1; +#ifdef CONFIG_UTF_8 /* UTF-8 I/O */ unsigned int utf8:1; +#endif /* CONFIG_UTF_8 */ /* The terminal._template_ name. */ unsigned char name[1]; /* XXX: Keep last! */ @@ -131,56 +142,81 @@ struct screen_driver { static struct screen_driver dumb_screen_driver = { NULL_LIST_HEAD, /* type: */ TERM_DUMB, +#ifndef CONFIG_UTF_8 + /* charsets: */ { -1, -1 }, /* No UTF8 I/O */ +#endif /* CONFIG_UTF_8 */ /* frame: */ frame_dumb, /* frame_seqs: */ NULL, /* underline: */ underline_seqs, /* color_mode: */ COLOR_MODE_16, /* transparent: */ 1, +#ifdef CONFIG_UTF_8 /* utf-8: */ 0, +#endif /* CONFIG_UTF_8 */ }; static struct screen_driver vt100_screen_driver = { NULL_LIST_HEAD, /* type: */ TERM_VT100, +#ifndef CONFIG_UTF_8 + /* charsets: */ { -1, -1 }, /* No UTF8 I/O */ +#endif /* CONFIG_UTF_8 */ /* frame: */ frame_vt100, /* frame_seqs: */ vt100_frame_seqs, /* underline: */ underline_seqs, /* color_mode: */ COLOR_MODE_16, /* transparent: */ 1, +#ifdef CONFIG_UTF_8 /* utf-8: */ 0, +#endif /* CONFIG_UTF_8 */ }; static struct screen_driver linux_screen_driver = { NULL_LIST_HEAD, /* type: */ TERM_LINUX, +#ifndef CONFIG_UTF_8 + /* charsets: */ { -1, -1 }, /* No UTF8 I/O */ +#endif /* CONFIG_UTF_8 */ /* frame: */ NULL, /* No restrict_852 */ /* frame_seqs: */ NULL, /* No m11_hack */ /* underline: */ underline_seqs, /* color_mode: */ COLOR_MODE_16, /* transparent: */ 1, +#ifdef CONFIG_UTF_8 /* utf-8: */ 0, +#endif /* CONFIG_UTF_8 */ }; static struct screen_driver koi8_screen_driver = { NULL_LIST_HEAD, /* type: */ TERM_KOI8, +#ifndef CONFIG_UTF_8 + /* charsets: */ { -1, -1 }, /* No UTF8 I/O */ +#endif /* CONFIG_UTF_8 */ /* frame: */ frame_koi, /* frame_seqs: */ NULL, /* underline: */ underline_seqs, /* color_mode: */ COLOR_MODE_16, /* transparent: */ 1, +#ifdef CONFIG_UTF_8 /* utf-8: */ 0, +#endif /* CONFIG_UTF_8 */ }; static struct screen_driver freebsd_screen_driver = { NULL_LIST_HEAD, /* type: */ TERM_FREEBSD, +#ifndef CONFIG_UTF_8 + /* charsets: */ { -1, -1 }, /* No UTF8 I/O */ +#endif /* CONFIG_UTF_8 */ /* frame: */ frame_freebsd, /* frame_seqs: */ NULL, /* No m11_hack */ /* underline: */ underline_seqs, /* color_mode: */ COLOR_MODE_16, /* transparent: */ 1, +#ifdef CONFIG_UTF_8 /* utf-8: */ 0, +#endif /* CONFIG_UTF_8 */ }; /* XXX: Keep in sync with enum term_mode_type. */ @@ -192,14 +228,22 @@ static struct screen_driver *screen_drivers[] = { /* TERM_FREEBSD: */ &freebsd_screen_driver, }; +#ifdef CONFIG_UTF_8 #define use_utf8_io(driver) ((driver)->utf8) +#else +#define use_utf8_io(driver) ((driver)->charsets[0] != -1) +#endif /* CONFIG_UTF_8 */ static INIT_LIST_HEAD(active_screen_drivers); static void update_screen_driver(struct screen_driver *driver, struct option *term_spec) { +#ifdef CONFIG_UTF_8 driver->utf8 = get_opt_bool_tree(term_spec, "utf_8_io"); +#else + int utf8_io = get_opt_bool_tree(term_spec, "utf_8_io"); +#endif /* CONFIG_UTF_8 */ driver->color_mode = get_opt_int_tree(term_spec, "colors"); driver->transparent = get_opt_bool_tree(term_spec, "transparency"); @@ -210,6 +254,7 @@ update_screen_driver(struct screen_driver *driver, struct option *term_spec) driver->underline = NULL; } +#ifdef CONFIG_UTF_8 if (driver->type == TERM_LINUX) { if (get_opt_bool_tree(term_spec, "restrict_852")) driver->frame = frame_restrict; @@ -227,6 +272,46 @@ update_screen_driver(struct screen_driver *driver, struct option *term_spec) } else if (driver->type == TERM_VT100) { driver->frame = frame_vt100; } +#else + if (utf8_io) { + driver->charsets[0] = get_opt_codepage_tree(term_spec, "charset"); + if (driver->type == TERM_LINUX) { + if (get_opt_bool_tree(term_spec, "restrict_852")) + driver->frame = frame_restrict; + + driver->charsets[1] = get_cp_index("cp437"); + + } else if (driver->type == TERM_FREEBSD) { + driver->charsets[1] = get_cp_index("cp437"); + + } else if (driver->type == TERM_VT100) { + driver->frame = frame_vt100_u; + driver->charsets[1] = get_cp_index("cp437"); + + } else if (driver->type == TERM_KOI8) { + driver->charsets[1] = get_cp_index("koi8-r"); + + } else { + driver->charsets[1] = driver->charsets[0]; + } + + } else { + driver->charsets[0] = -1; + if (driver->type == TERM_LINUX) { + if (get_opt_bool_tree(term_spec, "restrict_852")) + driver->frame = frame_restrict; + + if (get_opt_bool_tree(term_spec, "m11_hack")) + driver->frame_seqs = m11_hack_frame_seqs; + + } else if (driver->type == TERM_FREEBSD) { + if (get_opt_bool_tree(term_spec, "m11_hack")) + driver->frame_seqs = m11_hack_frame_seqs; + } else if (driver->type == TERM_VT100) { + driver->frame = frame_vt100; + } + } +#endif /* CONFIG_UTF_8 */ } static int @@ -265,7 +350,9 @@ add_screen_driver(enum term_mode_type type, struct terminal *term, int env_len) term->spec->change_hook = screen_driver_change_hook; +#ifdef CONFIG_UTF_8 term->utf8 = use_utf8_io(driver); +#endif /* CONFIG_UTF_8 */ return driver; } @@ -285,7 +372,9 @@ get_screen_driver(struct terminal *term) /* Some simple probably useless MRU ;) */ move_to_top_of_list(active_screen_drivers, driver); +#ifdef CONFIG_UTF_8 term->utf8 = use_utf8_io(driver); +#endif /* CONFIG_UTF_8 */ return driver; } @@ -351,10 +440,15 @@ struct screen_state { #define compare_bg_color(a, b) (TERM_COLOR_BACKGROUND(a) == TERM_COLOR_BACKGROUND(b)) #define compare_fg_color(a, b) (TERM_COLOR_FOREGROUND(a) == TERM_COLOR_FOREGROUND(b)) - +#ifdef CONFIG_UTF_8 static inline void add_char_data(struct string *screen, struct screen_driver *driver, unicode_val_T data, unsigned char border) +#else +static inline void +add_char_data(struct string *screen, struct screen_driver *driver, + unsigned char data, unsigned char border) +#endif /* CONFIG_UTF_8 */ { if (!isscreensafe(data)) { add_char_to_string(screen, ' '); @@ -365,11 +459,17 @@ add_char_data(struct string *screen, struct screen_driver *driver, data = driver->frame[data - 176]; if (use_utf8_io(driver)) { +#ifdef CONFIG_UTF_8 if (border) add_char_to_string(screen, (unsigned char)data); else if (data != UCS_NO_CHAR) add_to_string(screen, encode_utf_8(data)); +#else + int charset = driver->charsets[!!border]; + + add_to_string(screen, cp2utf_8(charset, data)); +#endif /* CONFIG_UTF_8 */ return; } diff --git a/src/terminal/terminal.h b/src/terminal/terminal.h index 685afb0a..80a5ad8f 100644 --- a/src/terminal/terminal.h +++ b/src/terminal/terminal.h @@ -110,8 +110,10 @@ struct terminal { * work and even maintaining these structures ;-). */ unsigned int master:1; +#ifdef CONFIG_UTF_8 /* Indicates whether UTF-8 I/O is used */ unsigned int utf8:1; +#endif /* CONFIG_UTF_8 */ /* The current tab number. */ int current_tab; diff --git a/src/viewer/dump/dump.c b/src/viewer/dump/dump.c index 6a50fa04..dcfb7f3e 100644 --- a/src/viewer/dump/dump.c +++ b/src/viewer/dump/dump.c @@ -323,8 +323,10 @@ add_document_to_string(struct string *string, struct document *document) assert(string && document); if_assert_failed return NULL; +#ifdef CONFIG_UTF_8 if (is_cp_special(document->options.cp)) goto utf_8; +#endif /* CONFIG_UTF_8 */ for (y = 0; y < document->height; y++) { int white = 0; @@ -358,6 +360,7 @@ add_document_to_string(struct string *string, struct document *document) add_char_to_string(string, '\n'); } +#ifdef CONFIG_UTF_8 goto end; utf_8: for (y = 0; y < document->height; y++) { @@ -395,6 +398,7 @@ utf_8: add_char_to_string(string, '\n'); } end: +#endif /* CONFIG_UTF_8 */ return string; } @@ -422,8 +426,10 @@ dump_to_file(struct document *document, int fd) if (!buf) return -1; +#ifdef CONFIG_UTF_8 if (is_cp_special(document->options.cp)) goto utf_8; +#endif /* CONFIG_UTF_8 */ for (y = 0; y < document->height; y++) { int white = 0; @@ -461,6 +467,7 @@ dump_to_file(struct document *document, int fd) if (write_char('\n', fd, buf, &bptr)) goto fail; } +#ifdef CONFIG_UTF_8 goto ref; utf_8: for (y = 0; y < document->height; y++) { @@ -508,13 +515,16 @@ utf_8: if (write_char('\n', fd, buf, &bptr)) goto fail; } +#endif /* CONFIG_UTF_8 */ if (hard_write(fd, buf, bptr) != bptr) { fail: mem_free(buf); return -1; } +#ifdef CONFIG_UTF_8 ref: +#endif /* CONFIG_UTF_8 */ if (document->nlinks && get_opt_bool("document.dump.references")) { int x; unsigned char *header = "\nReferences\n\n Visible links\n"; diff --git a/src/viewer/text/form.c b/src/viewer/text/form.c index 530fe83e..814b3f35 100644 --- a/src/viewer/text/form.c +++ b/src/viewer/text/form.c @@ -158,21 +158,27 @@ init_form_state(struct form_control *fc, struct form_state *fs) mem_free_set(&fs->value, NULL); switch (fc->type) { +#ifdef CONFIG_UTF_8 unsigned char *text; +#endif /* CONFIG_UTF_8 */ case FC_TEXT: case FC_PASSWORD: case FC_TEXTAREA: fs->value = stracpy(fc->default_value); fs->state = strlen(fc->default_value); +#ifdef CONFIG_UTF_8 text = fs->value; fs->utf8_pos = strlen_utf8(&text); +#endif /* CONFIG_UTF_8 */ fs->vpos = 0; break; case FC_FILE: fs->value = stracpy(""); fs->state = 0; +#ifdef CONFIG_UTF_8 fs->utf8_pos = 0; +#endif /* CONFIG_UTF_8 */ fs->vpos = 0; break; case FC_SELECT: @@ -335,14 +341,18 @@ draw_form_entry(struct terminal *term, struct document_view *doc_view, dy = box->y - vs->y; switch (fc->type) { unsigned char *s; +#ifdef CONFIG_UTF_8 unsigned char *text, *end; +#endif /* CONFIG_UTF_8 */ int len; int i, x, y; case FC_TEXT: case FC_PASSWORD: case FC_FILE: +#ifdef CONFIG_UTF_8 if (term->utf8) goto utf_8; +#endif /* CONFIG_UTF_8 */ int_bounds(&fs->vpos, fs->state - fc->size + 1, fs->state); if (!link->npoints) break; @@ -367,6 +377,7 @@ draw_form_entry(struct terminal *term, struct document_view *doc_view, draw_char_data(term, x, y, data); } break; +#ifdef CONFIG_UTF_8 utf_8: text = fs->value; end = strchr(text, '\0'); @@ -397,6 +408,7 @@ utf_8: draw_char_data(term, x, y, data); } break; +#endif /* CONFIG_UTF_8 */ case FC_TEXTAREA: draw_textarea(term, fs, doc_view, link); break; @@ -415,7 +427,9 @@ utf_8: else /* XXX: when can this happen? --pasky */ s = ""; +#ifdef CONFIG_UTF_8 if (term->utf8) goto utf_8_select; +#endif /* CONFIG_UTF_8 */ len = s ? strlen(s) : 0; for (i = 0; i < link->npoints; i++) { x = link->points[i].x + dx; @@ -424,6 +438,7 @@ utf_8: draw_char_data(term, x, y, i < len ? s[i] : '_'); } break; +#ifdef CONFIG_UTF_8 utf_8_select: text = s; end = strchr(s, '\0'); @@ -436,6 +451,7 @@ utf_8_select: ? utf_8_to_unicode(&s, end) : '_'); } break; +#endif /* CONFIG_UTF_8 */ case FC_SUBMIT: case FC_IMAGE: case FC_RESET: @@ -1245,7 +1261,9 @@ field_op(struct session *ses, struct document_view *doc_view, unsigned char *text; int length; enum frame_event_status status = FRAME_EVENT_REFRESH; +#ifdef CONFIG_UTF_8 int utf8 = ses->tab->term->utf8; +#endif /* CONFIG_UTF_8 */ assert(ses && doc_view && link && ev); if_assert_failed return FRAME_EVENT_OK; @@ -1265,6 +1283,7 @@ field_op(struct session *ses, struct document_view *doc_view, switch (action_id) { case ACT_EDIT_LEFT: +#ifdef CONFIG_UTF_8 if (utf8) { unsigned char *text = fs->value; unsigned char *end = fs->value + fs->state - 1; @@ -1274,9 +1293,11 @@ field_op(struct session *ses, struct document_view *doc_view, fs->state = (int)(text - fs->value); if (old != fs->state) fs->utf8_pos--; } else +#endif /* CONFIG_UTF_8 */ fs->state = int_max(fs->state - 1, 0); break; case ACT_EDIT_RIGHT: +#ifdef CONFIG_UTF_8 if (utf8) { unsigned char *text = fs->value + fs->state; unsigned char *end = strchr(text, '\0'); @@ -1286,58 +1307,91 @@ field_op(struct session *ses, struct document_view *doc_view, fs->state = (int)(text - fs->value); if (old != fs->state) fs->utf8_pos++; } else +#endif /* CONFIG_UTF_8 */ fs->state = int_min(fs->state + 1, strlen(fs->value)); break; case ACT_EDIT_HOME: if (fc->type == FC_TEXTAREA) { +#ifdef CONFIG_UTF_8 status = textarea_op_home(fs, fc, utf8); +#else + status = textarea_op_home(fs, fc); +#endif /* CONFIG_UTF_8 */ } else { fs->state = 0; +#ifdef CONFIG_UTF_8 fs->utf8_pos = 0; +#endif /* CONFIG_UTF_8 */ } break; case ACT_EDIT_UP: if (fc->type != FC_TEXTAREA) status = FRAME_EVENT_IGNORED; else +#ifdef CONFIG_UTF_8 status = textarea_op_up(fs, fc, utf8); +#else + status = textarea_op_up(fs, fc); +#endif /* CONFIG_UTF_8 */ break; case ACT_EDIT_DOWN: if (fc->type != FC_TEXTAREA) status = FRAME_EVENT_IGNORED; else +#ifdef CONFIG_UTF_8 status = textarea_op_down(fs, fc, utf8); +#else + status = textarea_op_down(fs, fc); +#endif /* CONFIG_UTF_8 */ break; case ACT_EDIT_END: if (fc->type == FC_TEXTAREA) { +#ifdef CONFIG_UTF_8 status = textarea_op_end(fs, fc, utf8); +#else + status = textarea_op_end(fs, fc); +#endif /* CONFIG_UTF_8 */ } else { fs->state = strlen(fs->value); +#ifdef CONFIG_UTF_8 if (utf8) { unsigned char *text = fs->value; fs->utf8_pos = strlen_utf8(&text); } +#endif /* CONFIG_UTF_8 */ } break; case ACT_EDIT_BEGINNING_OF_BUFFER: if (fc->type == FC_TEXTAREA) { +#ifdef CONFIG_UTF_8 status = textarea_op_bob(fs, fc, utf8); +#else + status = textarea_op_bob(fs, fc); +#endif /* CONFIG_UTF_8 */ } else { fs->state = 0; +#ifdef CONFIG_UTF_8 fs->utf8_pos = 0; +#endif /* CONFIG_UTF_8 */ } break; case ACT_EDIT_END_OF_BUFFER: if (fc->type == FC_TEXTAREA) { +#ifdef CONFIG_UTF_8 status = textarea_op_eob(fs, fc, utf8); +#else + status = textarea_op_eob(fs, fc); +#endif /* CONFIG_UTF_8 */ } else { fs->state = strlen(fs->value); +#ifdef CONFIG_UTF_8 if (utf8) { unsigned char *text = fs->value; fs->utf8_pos = strlen_utf8(&text); } +#endif /* CONFIG_UTF_8 */ } break; case ACT_EDIT_OPEN_EXTERNAL: @@ -1355,7 +1409,9 @@ field_op(struct session *ses, struct document_view *doc_view, if (!form_field_is_readonly(fc)) fs->value[0] = 0; fs->state = 0; +#ifdef CONFIG_UTF_8 fs->utf8_pos = 0; +#endif /* CONFIG_UTF_8 */ break; case ACT_EDIT_PASTE_CLIPBOARD: if (form_field_is_readonly(fc)) break; @@ -1371,19 +1427,24 @@ field_op(struct session *ses, struct document_view *doc_view, fs->value = v; memmove(v, text, length + 1); fs->state = strlen(fs->value); +#ifdef CONFIG_UTF_8 if (utf8 && fc->type != FC_TEXTAREA) { unsigned char *text = fs->value; fs->utf8_pos = strlen_utf8(&text); } - +#endif /* CONFIG_UTF_8 */ } } mem_free(text); break; case ACT_EDIT_ENTER: if (fc->type == FC_TEXTAREA) { +#ifdef CONFIG_UTF_8 status = textarea_op_enter(fs, fc, utf8); +#else + status = textarea_op_enter(fs, fc); +#endif /* CONFIG_UTF_8 */ break; } @@ -1408,6 +1469,7 @@ field_op(struct session *ses, struct document_view *doc_view, status = FRAME_EVENT_OK; break; } +#ifdef CONFIG_UTF_8 if (utf8) { int i; unsigned char *text = fs->value; @@ -1421,6 +1483,7 @@ field_op(struct session *ses, struct document_view *doc_view, fs->utf8_pos--; break; } +#endif /* CONFIG_UTF_8 */ length = strlen(fs->value + fs->state) + 1; text = fs->value + fs->state; @@ -1438,6 +1501,7 @@ field_op(struct session *ses, struct document_view *doc_view, status = FRAME_EVENT_OK; break; } +#ifdef CONFIG_UTF_8 if (utf8) { unsigned char *end = fs->value + length; unsigned char *text = fs->value + fs->state; @@ -1450,6 +1514,7 @@ field_op(struct session *ses, struct document_view *doc_view, } break; } +#endif /* CONFIG_UTF_8 */ text = fs->value + fs->state; memmove(text, text + 1, length - fs->state); @@ -1479,11 +1544,13 @@ field_op(struct session *ses, struct document_view *doc_view, memmove(text, fs->value + fs->state, length); fs->state = (int) (text - fs->value); +#ifdef CONFIG_UTF_8 if (utf8 && fc->type != FC_TEXTAREA) { unsigned char *text = fs->value; fs->utf8_pos = strlen_utf8(&text); } +#endif /* CONFIG_UTF_8 */ break; case ACT_EDIT_KILL_TO_EOL: if (form_field_is_readonly(fc)) { @@ -1537,10 +1604,16 @@ field_op(struct session *ses, struct document_view *doc_view, } if (form_field_is_readonly(fc) - || strlen(fs->value) >= fc->maxlength) { + || strlen(fs->value) >= fc->maxlength +#ifndef CONFIG_UTF_8 + || !insert_in_string(&fs->value, fs->state, "?", 1) +#endif /* CONFIG_UTF_8 */ + ) + { status = FRAME_EVENT_OK; break; } +#ifdef CONFIG_UTF_8 if (utf8) { static unsigned char buf[7]; static int i = 0; @@ -1572,6 +1645,9 @@ field_op(struct session *ses, struct document_view *doc_view, return FRAME_EVENT_OK; fs->value[fs->state++] = get_kbd_key(ev); } +#else + fs->value[fs->state++] = get_kbd_key(ev); +#endif /* CONFIG_UTF_8 */ break; } diff --git a/src/viewer/text/form.h b/src/viewer/text/form.h index fd034cfb..0f9658c3 100644 --- a/src/viewer/text/form.h +++ b/src/viewer/text/form.h @@ -39,7 +39,9 @@ struct form_state { unsigned char *value; int state; +#ifdef CONFIG_UTF_8 int utf8_pos; +#endif /* CONFIG_UTF_8 */ int vpos; int vypos; diff --git a/src/viewer/text/link.c b/src/viewer/text/link.c index 2fec2f42..68890689 100644 --- a/src/viewer/text/link.c +++ b/src/viewer/text/link.c @@ -112,7 +112,9 @@ get_link_cursor_offset(struct document_view *doc_view, struct link *link) { struct form_control *fc; struct form_state *fs; +#ifdef CONFIG_UTF_8 int utf8 = doc_view->document->options.utf8; +#endif /* CONFIG_UTF_8 */ switch (link->type) { case LINK_CHECKBOX: @@ -124,15 +126,21 @@ get_link_cursor_offset(struct document_view *doc_view, struct link *link) case LINK_FIELD: fc = get_link_form_control(link); fs = find_form_state(doc_view, fc); +#ifdef CONFIG_UTF_8 if (utf8) { return fs ? fs->utf8_pos - fs->vpos : 0; } else +#endif /* CONFIG_UTF_8 */ return fs ? fs->state - fs->vpos : 0; case LINK_AREA: fc = get_link_form_control(link); fs = find_form_state(doc_view, fc); +#ifdef CONFIG_UTF_8 return fs ? area_cursor(fc, fs, utf8) : 0; +#else + return fs ? area_cursor(fc, fs) : 0; +#endif /* CONFIG_UTF_8 */ case LINK_HYPERTEXT: case LINK_MAP: diff --git a/src/viewer/text/textarea.c b/src/viewer/text/textarea.c index 8dca3b00..ab5920ec 100644 --- a/src/viewer/text/textarea.c +++ b/src/viewer/text/textarea.c @@ -47,6 +47,7 @@ struct line_info { #define realloc_line_info(info, size) \ mem_align_alloc(info, size, (size) + 3, 0xFF) +#ifdef CONFIG_UTF_8 /* Allocates a line_info table describing the layout of the textarea buffer. * * @width is max width and the offset at which text will be wrapped @@ -117,6 +118,7 @@ format_textutf8(unsigned char *text, int width, enum form_wrap wrap, int format) return line; } +#endif /* CONFIG_UTF_8 */ /* Allocates a line_info table describing the layout of the textarea buffer. * @@ -209,7 +211,11 @@ get_textarea_line_number(struct line_info *line, int cursor_position) /* Fixes up the vpos and vypos members of the form_state. Returns the * logical position in the textarea view. */ int +#ifdef CONFIG_UTF_8 area_cursor(struct form_control *fc, struct form_state *fs, int utf8) +#else +area_cursor(struct form_control *fc, struct form_state *fs) +#endif /* CONFIG_UTF_8 */ { struct line_info *line; int x, y; @@ -217,9 +223,11 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8) assert(fc && fs); if_assert_failed return 0; +#ifdef CONFIG_UTF_8 if (utf8) line = format_textutf8(fs->value, fc->cols, fc->wrap, 0); else +#endif /* CONFIG_UTF_8 */ line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return 0; @@ -228,7 +236,7 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8) mem_free(line); return 0; } - +#ifdef CONFIG_UTF_8 if (utf8) { unsigned char *text = fs->value + line[y].start; unsigned char tmp = fs->value[fs->state]; @@ -237,6 +245,7 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8) x = strlen_utf8(&text); fs->value[fs->state] = tmp; } else +#endif /* CONFIG_UTF_8 */ x = fs->state - line[y].start; mem_free(line); @@ -252,6 +261,7 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8) return y * fc->cols + x; } +#ifdef CONFIG_UTF_8 static void draw_textarea_utf8(struct terminal *term, struct form_state *fs, struct document_view *doc_view, struct link *link) @@ -329,7 +339,7 @@ draw_textarea_utf8(struct terminal *term, struct form_state *fs, mem_free(linex); } - +#endif /* CONFIG_UTF_8 */ void draw_textarea(struct terminal *term, struct form_state *fs, @@ -345,10 +355,12 @@ draw_textarea(struct terminal *term, struct form_state *fs, assert(term && doc_view && doc_view->document && doc_view->vs && link); if_assert_failed return; +#ifdef CONFIG_UTF_8 if (term->utf8) { draw_textarea_utf8(term, fs, doc_view, link); return; } +#endif /* CONFIG_UTF_8 */ fc = get_link_form_control(link); assertm(fc, "link %d has no form control", (int) (link - doc_view->document->links)); if_assert_failed return; @@ -358,7 +370,11 @@ draw_textarea(struct terminal *term, struct form_state *fs, vy = doc_view->vs->y; if (!link->npoints) return; +#ifdef CONFIG_UTF_8 area_cursor(fc, fs, 0); +#else + area_cursor(fc, fs); +#endif /* CONFIG_UTF_8 */ linex = format_text(fs->value, fc->cols, fc->wrap, 0); if (!linex) return; line = linex; @@ -615,8 +631,13 @@ menu_textarea_edit(struct terminal *term, void *xxx, void *ses_) } static enum frame_event_status +#ifdef CONFIG_UTF_8 textarea_op(struct form_state *fs, struct form_control *fc, int utf8, int (*do_op)(struct form_state *, struct line_info *, int, int)) +#else +textarea_op(struct form_state *fs, struct form_control *fc, + int (*do_op)(struct form_state *, struct line_info *, int)) +#endif /* CONFIG_UTF_8 */ { struct line_info *line; int current, state; @@ -624,15 +645,22 @@ textarea_op(struct form_state *fs, struct form_control *fc, int utf8, assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; +#ifdef CONFIG_UTF_8 if (utf8) line = format_textutf8(fs->value, fc->cols, fc->wrap, 0); else +#endif /* CONFIG_UTF_8 */ line = format_text(fs->value, fc->cols, fc->wrap, 0); if (!line) return FRAME_EVENT_OK; current = get_textarea_line_number(line, fs->state); state = fs->state; - if (do_op(fs, line, current, utf8)) { +#ifdef CONFIG_UTF_8 + if (do_op(fs, line, current, utf8)) +#else + if (do_op(fs, line, current)) +#endif /* CONFIG_UTF_8 */ +{ mem_free(line); return FRAME_EVENT_IGNORED; } @@ -641,6 +669,7 @@ textarea_op(struct form_state *fs, struct form_control *fc, int utf8, return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH; } +#ifdef CONFIG_UTF_8 static int x_pos(struct form_state *fs, struct line_info *line, int current) { @@ -668,26 +697,37 @@ new_pos(struct form_state *fs, struct line_info *line, int current, int len) } fs->state = (int)(text - fs->value); } +#endif /* CONFIG_UTF_8 */ static int +#ifdef CONFIG_UTF_8 do_op_home(struct form_state *fs, struct line_info *line, int current, int utf8) +#else +do_op_home(struct form_state *fs, struct line_info *line, int current) +#endif /* CONFIG_UTF_8 */ { if (current != -1) fs->state = line[current].start; return 0; } static int +#ifdef CONFIG_UTF_8 do_op_up(struct form_state *fs, struct line_info *line, int current, int utf8) +#else +do_op_up(struct form_state *fs, struct line_info *line, int current) +#endif /* CONFIG_UTF_8 */ { if (current == -1) return 0; if (!current) return 1; +#ifdef CONFIG_UTF_8 if (utf8) { int len = x_pos(fs, line, current); new_pos(fs, line, current - 1, len); return 0; } +#endif /* CONFIG_UTF_8 */ fs->state -= line[current].start - line[current-1].start; int_upper_bound(&fs->state, line[current-1].end); @@ -695,24 +735,35 @@ do_op_up(struct form_state *fs, struct line_info *line, int current, int utf8) } static int +#ifdef CONFIG_UTF_8 do_op_down(struct form_state *fs, struct line_info *line, int current, int utf8) +#else +do_op_down(struct form_state *fs, struct line_info *line, int current) +#endif /* CONFIG_UTF_8 */ { if (current == -1) return 0; if (line[current+1].start == -1) return 1; +#ifdef CONFIG_UTF_8 if (utf8) { int len = x_pos(fs, line, current); new_pos(fs, line, current + 1, len); return 0; } +#endif /* CONFIG_UTF_8 */ + fs->state += line[current+1].start - line[current].start; int_upper_bound(&fs->state, line[current+1].end); return 0; } static int +#ifdef CONFIG_UTF_8 do_op_end(struct form_state *fs, struct line_info *line, int current, int utf8) +#else +do_op_end(struct form_state *fs, struct line_info *line, int current) +#endif /* CONFIG_UTF_8 */ { if (current == -1) { fs->state = strlen(fs->value); @@ -727,7 +778,11 @@ do_op_end(struct form_state *fs, struct line_info *line, int current, int utf8) } static int +#ifdef CONFIG_UTF_8 do_op_bob(struct form_state *fs, struct line_info *line, int current, int utf8) +#else +do_op_bob(struct form_state *fs, struct line_info *line, int current) +#endif /* CONFIG_UTF_8 */ { if (current == -1) return 0; @@ -737,7 +792,11 @@ do_op_bob(struct form_state *fs, struct line_info *line, int current, int utf8) } static int +#ifdef CONFIG_UTF_8 do_op_eob(struct form_state *fs, struct line_info *line, int current, int utf8) +#else +do_op_eob(struct form_state *fs, struct line_info *line, int current) +#endif /* CONFIG_UTF_8 */ { if (current == -1) { fs->state = strlen(fs->value); @@ -753,50 +812,102 @@ do_op_eob(struct form_state *fs, struct line_info *line, int current, int utf8) return 0; } +#ifdef CONFIG_UTF_8 enum frame_event_status textarea_op_home(struct form_state *fs, struct form_control *fc, int utf8) { return textarea_op(fs, fc, utf8, do_op_home); } +#else +enum frame_event_status +textarea_op_home(struct form_state *fs, struct form_control *fc) +{ + return textarea_op(fs, fc, do_op_home); +} +#endif /* CONFIG_UTF_8 */ +#ifdef CONFIG_UTF_8 enum frame_event_status textarea_op_up(struct form_state *fs, struct form_control *fc, int utf8) { return textarea_op(fs, fc, utf8, do_op_up); } +#else +enum frame_event_status +textarea_op_up(struct form_state *fs, struct form_control *fc) +{ + return textarea_op(fs, fc, do_op_up); +} +#endif /* CONFIG_UTF_8 */ +#ifdef CONFIG_UTF_8 enum frame_event_status textarea_op_down(struct form_state *fs, struct form_control *fc, int utf8) { return textarea_op(fs, fc, utf8, do_op_down); } +#else +enum frame_event_status +textarea_op_down(struct form_state *fs, struct form_control *fc) +{ + return textarea_op(fs, fc, do_op_down); +} +#endif /* CONFIG_UTF_8 */ +#ifdef CONFIG_UTF_8 enum frame_event_status textarea_op_end(struct form_state *fs, struct form_control *fc, int utf8) { return textarea_op(fs, fc, utf8, do_op_end); } +#else +enum frame_event_status +textarea_op_end(struct form_state *fs, struct form_control *fc) +{ + return textarea_op(fs, fc, do_op_end); +} +#endif /* CONFIG_UTF_8 */ /* Set the form state so the cursor is on the first line of the buffer. * Preserve the column if possible. */ +#ifdef CONFIG_UTF_8 enum frame_event_status textarea_op_bob(struct form_state *fs, struct form_control *fc, int utf8) { return textarea_op(fs, fc, utf8, do_op_bob); } +#else +enum frame_event_status +textarea_op_bob(struct form_state *fs, struct form_control *fc) +{ + return textarea_op(fs, fc, do_op_bob); +} +#endif /* CONFIG_UTF_8 */ /* Set the form state so the cursor is on the last line of the buffer. Preserve * the column if possible. This is done by getting current and last line and * then shifting the state by the delta of both lines start position bounding * the whole thing to the end of the last line. */ +#ifdef CONFIG_UTF_8 enum frame_event_status textarea_op_eob(struct form_state *fs, struct form_control *fc, int utf8) { return textarea_op(fs, fc, utf8, do_op_eob); } +#else +enum frame_event_status +textarea_op_eob(struct form_state *fs, struct form_control *fc) +{ + return textarea_op(fs, fc, do_op_eob); +} +#endif /* CONFIG_UTF_8 */ enum frame_event_status +#ifdef CONFIG_UTF_8 textarea_op_enter(struct form_state *fs, struct form_control *fc, int utf8) +#else +textarea_op_enter(struct form_state *fs, struct form_control *fc) +#endif /* CONFIG_UTF_8 */ { assert(fs && fs->value && fc); if_assert_failed return FRAME_EVENT_OK; @@ -817,7 +928,9 @@ set_textarea(struct document_view *doc_view, int direction) struct form_control *fc; struct form_state *fs; struct link *link; +#ifdef CONFIG_UTF_8 int utf8 = doc_view->document->options.utf8; +#endif /* CONFIG_UTF_8 */ assert(doc_view && doc_view->vs && doc_view->document); assert(direction == 1 || direction == -1); @@ -838,8 +951,15 @@ set_textarea(struct document_view *doc_view, int direction) /* Depending on which way we entered the textarea move cursor so that * it is available at end or start. */ +#ifdef CONFIG_UTF_8 if (direction == 1) textarea_op_eob(fs, fc, utf8); else textarea_op_bob(fs, fc, utf8); +#else + if (direction == 1) + textarea_op_eob(fs, fc); + else + textarea_op_bob(fs, fc); +#endif /* CONFIG_UTF_8 */ } diff --git a/src/viewer/text/textarea.h b/src/viewer/text/textarea.h index 0a27f58f..462aa3e6 100644 --- a/src/viewer/text/textarea.h +++ b/src/viewer/text/textarea.h @@ -13,7 +13,11 @@ struct link; struct session; struct terminal; +#ifdef CONFIG_UTF_8 int area_cursor(struct form_control *fc, struct form_state *fs, int utf8); +#else +int area_cursor(struct form_control *fc, struct form_state *fs); +#endif /* CONFIG_UTF_8 */ void draw_textarea(struct terminal *term, struct form_state *fs, struct document_view *doc_view, struct link *link); unsigned char *encode_textarea(struct submitted_value *sv); @@ -21,6 +25,7 @@ extern int textarea_editor; void textarea_edit(int, struct terminal *, struct form_state *, struct document_view *, struct link *); void menu_textarea_edit(struct terminal *term, void *xxx, void *ses_); +#ifdef CONFIG_UTF_8 enum frame_event_status textarea_op_home(struct form_state *fs, struct form_control *fc, int utf8); enum frame_event_status textarea_op_up(struct form_state *fs, struct form_control *fc, int utf8); enum frame_event_status textarea_op_down(struct form_state *fs, struct form_control *fc, int utf8); @@ -28,6 +33,15 @@ enum frame_event_status textarea_op_end(struct form_state *fs, struct form_contr enum frame_event_status textarea_op_bob(struct form_state *fs, struct form_control *fc, int utf8); enum frame_event_status textarea_op_eob(struct form_state *fs, struct form_control *fc, int utf8); enum frame_event_status textarea_op_enter(struct form_state *fs, struct form_control *fc, int utf8); +#else +enum frame_event_status textarea_op_home(struct form_state *fs, struct form_control *fc); +enum frame_event_status textarea_op_up(struct form_state *fs, struct form_control *fc); +enum frame_event_status textarea_op_down(struct form_state *fs, struct form_control *fc); +enum frame_event_status textarea_op_end(struct form_state *fs, struct form_control *fc); +enum frame_event_status textarea_op_bob(struct form_state *fs, struct form_control *fc); +enum frame_event_status textarea_op_eob(struct form_state *fs, struct form_control *fc); +enum frame_event_status textarea_op_enter(struct form_state *fs, struct form_control *fc); +#endif /* CONFIG_UTF_8 */ void set_textarea(struct document_view *doc_view, int direction);