/* direction = TRUE (move forward), FALSE (move backward) Any error shall return length(text->text) or 0 or text->selection_end (as deemed fit) */static int_get_updated_position (EText *text, gboolean direction){ PangoLogAttr *log_attrs = NULL; gint n_attrs; char *p = NULL; gint new_pos = 0; gint length = 0; /* Basic sanity test, return whatever position we are currently at. */ g_return_val_if_fail (text->layout != NULL, text->selection_end); length = g_utf8_strlen (text->text, -1); /* length checks to make sure we are not wandering off into nonexistant memory... */ if((text->selection_end >= length) && (TRUE == direction)) /* forward */ return length; /* checking for -ve value wont hurt! */ if((text->selection_end <= 0) && (FALSE == direction)) /* backward */ return 0; /* check for validness of full text->text */ if(!g_utf8_validate(text->text, -1, NULL)) return text->selection_end; /* get layout's PangoLogAttr to facilitate moving when moving across grapheme cluster as in indic langs */ pango_layout_get_log_attrs (text->layout, &log_attrs, &n_attrs); /* Fetch the current char index in the line & keep moving forward until we can display cursor */ p = g_utf8_offset_to_pointer (text->text, text->selection_end); while(1) { /* check before moving forward/backwards if we have more chars to move or not */ if(TRUE == direction) p = g_utf8_next_char (p); else p = g_utf8_prev_char (p); /* validate the new string & return with original position if check fails */ if(!g_utf8_validate (p, -1, NULL)) return text->selection_end; new_pos = g_utf8_pointer_to_offset (text->text, p); g_print ("new_pos=%d, n_attrs=%d\n", new_pos, n_attrs); /* if is_cursor_position is set, cursor can appear in front of character. i.e. this is a grapheme boundary AND make some sanity checks */ if((new_pos >=0) && (new_pos < n_attrs) && (log_attrs[new_pos].is_cursor_position)) { g_print("Breaking\n"); break; } else if((new_pos < 0) || (new_pos >= n_attrs)) { g_print("returning text->selection_end=%d\n", text->selection_end); return text->selection_end; } } if(log_attrs) g_free(log_attrs); return new_pos;}