/* utiliti function, thah skip characters from cheked until ident is greater or * equal to to_ident */ static gboolean utf8_tool_skip_chars_to (struct utf8_tool *tool, int to_ident) { gunichar uni; while (to_ident > tool->ident && tool->cheked[0] != '\0') { uni = g_utf8_get_char (tool->cheked); if (!str_unichar_iscombiningmark (uni)) { tool->ident++; if (g_unichar_iswide (uni)) tool->ident++; } tool->cheked = g_utf8_next_char (tool->cheked); } uni = g_utf8_get_char (tool->cheked); while (str_unichar_iscombiningmark (uni)) { tool->cheked = g_utf8_next_char (tool->cheked); uni = g_utf8_get_char (tool->cheked); } return TRUE; }
/* utiliti function, that make string valid in utf8 and all characters printable * return width of string too*/ static const struct term_form * str_utf8_make_make_term_form (const char *text, size_t length) { static struct term_form result; gunichar uni; size_t left; char *actual; result.text[0] = '\0'; result.width = 0; result.compose = 0; actual = result.text; /* check if text start with combining character, * add space at begin in this case */ if (length != 0 && text[0] != '\0') { uni = g_utf8_get_char_validated (text, -1); if ((uni != (gunichar) (-1)) && (uni != (gunichar) (-2))) { if (str_unichar_iscombiningmark (uni)) { actual[0] = ' '; actual++; result.width++; result.compose = 1; } } } while (length != 0 && text[0] != '\0') { uni = g_utf8_get_char_validated (text, -1); if ((uni != (gunichar)(-1)) && (uni != (gunichar)(-2))) { if (g_unichar_isprint(uni)) { left = g_unichar_to_utf8 (uni, actual); actual+= left; if (!str_unichar_iscombiningmark (uni)) { result.width++; if (g_unichar_iswide(uni)) result.width++; } else result.compose = 1; } else { actual[0] = '.'; actual++; result.width++; } text = g_utf8_next_char (text); } else { text++; /*actual[0] = '?';*/ memcpy (actual, replch, strlen (replch)); actual+= strlen (replch); result.width++; } if (length != (size_t) (-1)) length--; } actual[0] = '\0'; return &result; }
static int str_utf8_term_char_width (const char *text) { gunichar uni = g_utf8_get_char_validated (text, -1); return (str_unichar_iscombiningmark (uni)) ? 0 : ((g_unichar_iswide (uni)) ? 2 : 1); }
/* utiliti function, that copy characters from cheked to actual until ident is * smaller than to_ident */ static gboolean utf8_tool_copy_chars_to (struct utf8_tool *tool, int to_ident) { tool->compose = FALSE; while (tool->cheked[0] != '\0') { gunichar uni; size_t left; int w = 0; uni = g_utf8_get_char (tool->cheked); if (str_unichar_iscombiningmark (uni)) tool->compose = TRUE; else { w = 1; if (g_unichar_iswide (uni)) w++; if (tool->ident + w > to_ident) return TRUE; } left = g_unichar_to_utf8 (uni, NULL); if (tool->remain <= left) return FALSE; left = g_unichar_to_utf8 (uni, tool->actual); tool->actual += left; tool->remain -= left; tool->cheked = g_utf8_next_char (tool->cheked); tool->ident += w; } return TRUE; }
static gboolean str_utf8_iscombiningmark (const char *ch) { gunichar uni; uni = g_utf8_get_char_validated (ch, -1); return str_unichar_iscombiningmark (uni); }
static int str_utf8_column_to_pos (const char *text, size_t pos) { static int result; gunichar uni; int width; width = 0; result = 0; while (text[0] != '\0') { uni = g_utf8_get_char_validated (text, 6); if ((uni != (gunichar) (-1)) && (uni != (gunichar) (-2))) { if (g_unichar_isprint (uni)) { if (!str_unichar_iscombiningmark (uni)) { width++; if (g_unichar_iswide (uni)) width++; } } else { width++; } text = g_utf8_next_char (text); } else { text++; width++; } if ((gsize)width > pos) return result; result++; } return result; }
/* utiliti function, that copy all characters from cheked to actual */ static int utf8_tool_copy_chars_to_end (struct utf8_tool *tool) { size_t left; gunichar uni; tool->compose = 0; while (tool->cheked[0] != '\0') { uni = g_utf8_get_char (tool->cheked); tool->compose |= str_unichar_iscombiningmark (uni); left = g_unichar_to_utf8 (uni, NULL); if (tool->remain <= left) return 0; left = g_unichar_to_utf8 (uni, tool->actual); tool->actual += left; tool->remain -= left; tool->cheked = g_utf8_next_char (tool->cheked); } return 1; }
/* utiliti function, that copy all characters from cheked to actual */ static gboolean utf8_tool_copy_chars_to_end (struct utf8_tool *tool) { tool->compose = FALSE; while (tool->cheked[0] != '\0') { gunichar uni; size_t left; uni = g_utf8_get_char (tool->cheked); tool->compose = tool->compose || str_unichar_iscombiningmark (uni); left = g_unichar_to_utf8 (uni, NULL); if (tool->remain <= left) return FALSE; left = g_unichar_to_utf8 (uni, tool->actual); tool->actual += left; tool->remain -= left; tool->cheked = g_utf8_next_char (tool->cheked); } return TRUE; }
/* utiliti function, that copy characters from cheked to actual until ident is * smaller than to_ident */ static int utf8_tool_copy_chars_to (struct utf8_tool *tool, int to_ident) { size_t left; gunichar uni; int w; tool->compose = 0; while (tool->cheked[0] != '\0') { uni = g_utf8_get_char (tool->cheked); if (!str_unichar_iscombiningmark (uni)) { w = 1; if (g_unichar_iswide (uni)) w++; if (tool->ident + w > to_ident) return 1; } else { w = 0; tool->compose = 1; } left = g_unichar_to_utf8 (uni, NULL); if (tool->remain <= left) return 0; left = g_unichar_to_utf8 (uni, tool->actual); tool->actual += left; tool->remain -= left; tool->cheked = g_utf8_next_char (tool->cheked); tool->ident += w; } return 1; }