aboutsummaryrefslogtreecommitdiff
path: root/libstorycode/gtk
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.me.uk>2024-09-01 15:40:56 +0200
committerThomas White <taw@bitwiz.me.uk>2024-09-01 15:42:14 +0200
commit20445851914403052d61a137f2d207bf23791cf2 (patch)
treea6ab35f1727fac54ccf69ffe2c3a40c61d62a349 /libstorycode/gtk
parent74999acb4c11760103ce2bd853a9f08c2e3106e0 (diff)
Fix character offset when stepping back one paragraphHEADmaster
Diffstat (limited to 'libstorycode/gtk')
-rw-r--r--libstorycode/gtk/gtknarrativeview.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/libstorycode/gtk/gtknarrativeview.c b/libstorycode/gtk/gtknarrativeview.c
index 3b98b8a..2f72b54 100644
--- a/libstorycode/gtk/gtknarrativeview.c
+++ b/libstorycode/gtk/gtknarrativeview.c
@@ -605,6 +605,35 @@ static size_t gtknv_end_offset_of_para(Narrative *n, int pnum)
}
+static int has_nonempty_run(Narrative *n, int pnum)
+{
+ assert(pnum >= 0);
+ if ( !narrative_item_is_text(n, pnum) ) return 0;
+ if ( n->items[pnum].n_runs == 0 ) return 0;
+ return strlen(n->items[pnum].runs[0].text) > 0;
+}
+
+
+static int last_char_pos(struct narrative_item *p)
+{
+ gchar *end_char;
+ int i;
+ size_t len = 0;
+ int l;
+ gchar *txt;
+
+ if ( p->n_runs == 0 ) return 0;
+
+ l = p->n_runs-1;
+ for ( i=0; i<l; i++ ) {
+ len += strlen(p->runs[i].text);
+ }
+ txt = p->runs[l].text;
+ end_char = g_utf8_find_prev_char(txt, &txt[strlen(txt)]);
+ return len + end_char - txt;
+}
+
+
static void sort_positions(struct edit_pos *a, struct edit_pos *b)
{
if ( a->para > b->para ) {
@@ -656,11 +685,9 @@ static void gtknv_cursor_moveh(Narrative *n, struct edit_pos *cp, signed int dir
if ( np == -1 ) {
if ( cp->para > 0 ) {
- size_t end_offs;
cp->para--;
- end_offs = gtknv_end_offset_of_para(n, cp->para);
- if ( end_offs > 0 ) {
- cp->pos = end_offs - 1;
+ if ( has_nonempty_run(n, cp->para) ) {
+ cp->pos = last_char_pos(&n->items[cp->para]);
cp->trail = 1;
} else {
/* Jumping into an empty paragraph */