int utf8len(const char *s, int len){ const char *p = s; int n = 0, nc = 0; while(*p != '\0' && n < len){ int k = utf8charlen(*p); n += k; nc++; p += k; } if(n > len) return -1; return nc; }
static inline const char* skipChar( const char* si) { unsigned char charsize = utf8charlen( *si); if (!charsize) { throw strus::runtime_error(_TXT( "illegal UTF-8 character in input: %u"), (unsigned int)(unsigned char)*si); } else { return si+charsize; } }
char *utf8substr(const char *s, int len){ int n = 0, size = 0; const char *p = s; int l; while((l = utf8charlen(*p)) && n != len){ p += l; size += l; n++; } if(l == 0) size++; char *str = new char[size + 1]; strncpy(str, s, size); str[size] = '\0'; return str; }
static widget_handler_status_T display_button(struct dialog_data *dlg_data, struct widget_data *widget_data) { struct terminal *term = dlg_data->win->term; struct color_pair *color, *shortcut_color; struct el_box *pos = &widget_data->box; int len, x; int sel = is_selected_widget(dlg_data, widget_data); if (sel) { shortcut_color = get_bfu_color(term, "dialog.button-shortcut-selected"); color = get_bfu_color(term, "dialog.button-selected"); } else { shortcut_color = get_bfu_color(term, "dialog.button-shortcut"); color = get_bfu_color(term, "dialog.button"); } if (!color || !shortcut_color) return EVENT_PROCESSED; #ifdef CONFIG_UTF8 if (term->utf8_cp) { int button_left_len = utf8_ptr2cells(BUTTON_LEFT, NULL); int button_right_len = utf8_ptr2cells(BUTTON_RIGHT, NULL); x = pos->x + button_left_len; len = widget_data->box.width - (button_left_len + button_right_len); } else #endif /* CONFIG_UTF8 */ { x = pos->x + BUTTON_LEFT_LEN; len = widget_data->box.width - BUTTON_LR_LEN; } draw_dlg_text(dlg_data, pos->x, pos->y, BUTTON_LEFT, BUTTON_LEFT_LEN, 0, color); if (len > 0) { unsigned char *text = widget_data->widget->text; int hk_pos = widget_data->widget->info.button.hotkey_pos; int attr; attr = get_opt_bool("ui.dialogs.underline_button_shortcuts", NULL) ? SCREEN_ATTR_UNDERLINE : 0; #ifdef CONFIG_UTF8 if (term->utf8_cp) { if (hk_pos >= 0) { int hk_bytes = utf8charlen(&text[hk_pos+1]); int cells_to_hk = utf8_ptr2cells(text, &text[hk_pos]); int right = widget_data->widget->info.button.truetextlen - hk_pos - hk_bytes; int hk_cells = utf8_char2cells(&text[hk_pos + 1], NULL); if (hk_pos) draw_dlg_text(dlg_data, x, pos->y, text, hk_pos, 0, color); draw_dlg_text(dlg_data, x + cells_to_hk, pos->y, &text[hk_pos + 1], hk_bytes, attr, shortcut_color); if (right > 1) draw_dlg_text(dlg_data, x+cells_to_hk+hk_cells, pos->y, &text[hk_pos + hk_bytes + 1], right - 1, 0, color); } else { int hk_width = utf8_char2cells(text, NULL); int hk_len = utf8charlen(text); int len_to_display = utf8_cells2bytes(&text[hk_len], len - hk_width, NULL); draw_dlg_text(dlg_data, x, pos->y, text, hk_len, attr, shortcut_color); draw_dlg_text(dlg_data, x + hk_width, pos->y, &text[hk_len], len_to_display, 0, color); } } else #endif /* CONFIG_UTF8 */ if (hk_pos >= 0) { int right = widget_data->widget->info.button.truetextlen - hk_pos - 1; if (hk_pos) { draw_dlg_text(dlg_data, x, pos->y, text, hk_pos, 0, color); } draw_dlg_text(dlg_data, x + hk_pos, pos->y, &text[hk_pos + 1], 1, attr, shortcut_color); if (right > 1) { draw_dlg_text(dlg_data, x + hk_pos + 1, pos->y, &text[hk_pos + 2], right - 1, 0, color); } } else { draw_dlg_text(dlg_data, x, pos->y, text, 1, attr, shortcut_color); draw_dlg_text(dlg_data, x + 1, pos->y, &text[1], len - 1, 0, color); } } #ifdef CONFIG_UTF8 if (term->utf8_cp) { int text_cells = utf8_ptr2cells(widget_data->widget->text, NULL); int hk = (widget_data->widget->info.button.hotkey_pos >= 0); draw_dlg_text(dlg_data, x + text_cells - hk, pos->y, BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color); } else #endif /* CONFIG_UTF8 */ draw_dlg_text(dlg_data, x + len, pos->y, BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color); if (sel) { set_dlg_cursor(term, dlg_data, x, pos->y, 1); set_dlg_window_ptr(dlg_data, dlg_data->win, pos->x, pos->y); } return EVENT_PROCESSED; }
const char *utf8nextchar(const char *s){ return s + utf8charlen(*s); }
/** Allocates a line_info table describing the layout of the textarea buffer. * * @param text the text to format; must be in UTF-8 * @param width is max width and the offset at which @a text will be * wrapped * @param wrap controls how the wrapping of @a text is performed * @param format is non zero the @a text will be modified to make it * suitable for encoding it for form posting */ static struct line_info * format_textutf8(unsigned char *text, int width, enum form_wrap wrap, int format) { struct line_info *line = NULL; int line_number = 0; int begin = 0; int pos = 0; unsigned char *text_end; int skip; unsigned char *wrappos=NULL; int chars_cells=0; /* Number of console chars on line */ assert(text); if_assert_failed return NULL; /* Allocate the ending entries */ if (!realloc_line_info(&line, 0)) return NULL; text_end = text + strlen(text); while (text[pos]) { int char_cells = utf8_char2cells(&text[pos], text_end); if (text[pos] == ' ') wrappos = &text[pos]; if (text[pos] == '\n') { skip = 1; } else if (wrap == FORM_WRAP_NONE || chars_cells + char_cells < width) { pos += utf8charlen(&text[pos]); chars_cells += char_cells; continue; } else { if (wrappos) { /* When formatting text for form submitting we * have to apply the wrapping mode. */ if (wrap == FORM_WRAP_HARD && format) *wrappos = '\n'; pos = wrappos - text; } skip = !!wrappos; } if (!realloc_line_info(&line, line_number)) { mem_free_if(line); return NULL; } line[line_number].last_char_width = char_cells; line[line_number].split_next = !skip; line[line_number].start = begin; line[line_number++].end = pos; line[line_number].split_prev = !skip; begin = pos += skip; chars_cells = 0; wrappos = NULL; } line[line_number].split_next = 0; /* Flush the last text before the loop ended */ line[line_number].start = begin; line[line_number++].end = pos; /* Add end marker */ line[line_number].start = line[line_number].end = -1; line[line_number].split_next = line[line_number].split_prev = 0; line[0].split_prev = 0; return line; }