diff options
-rw-r--r-- | src/frame.c | 19 | ||||
-rw-r--r-- | src/frame.h | 2 | ||||
-rw-r--r-- | src/sc_editor.c | 43 |
3 files changed, 51 insertions, 13 deletions
diff --git a/src/frame.c b/src/frame.c index 11c6d8f..5c20437 100644 --- a/src/frame.c +++ b/src/frame.c @@ -764,6 +764,25 @@ static int which_run(Paragraph *para, size_t offs) } +size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail) +{ + glong char_offs; + const char *run_text; + struct text_run *run; + int nrun; + char *ptr; + + nrun = which_run(para, offs); + run= ¶->runs[nrun]; + run_text = sc_block_contents(run->scblock) + run->scblock_offs_bytes; + char_offs = g_utf8_pointer_to_offset(run_text, run_text+offs); + char_offs += trail; + + ptr = g_utf8_offset_to_pointer(run_text, char_offs); + return ptr - run_text; +} + + void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t) { int nrun; diff --git a/src/frame.h b/src/frame.h index bf09e52..7f9c920 100644 --- a/src/frame.h +++ b/src/frame.h @@ -156,6 +156,8 @@ extern void cursor_movev(struct frame *fr, int *cpara, size_t *cpos, int *ctrail extern void check_callback_click(struct frame *fr, int para); +extern size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail); + extern void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t); diff --git a/src/sc_editor.c b/src/sc_editor.c index 4b4a601..5aeb003 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -593,17 +593,24 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, SCEditor *e) SCBlock *split_paragraph_at_cursor(SCEditor *e) { - return split_paragraph(e->cursor_frame, e->cursor_para, - e->cursor_pos+e->cursor_trail, e->pc); + size_t offs; + Paragraph *para; + + para = e->cursor_frame->paras[e->cursor_para]; + offs = pos_trail_to_offset(para, e->cursor_pos, e->cursor_trail); + return split_paragraph(e->cursor_frame, e->cursor_para, offs, e->pc); } static void check_cursor_visible(SCEditor *e) { double x, y, h; + size_t offs; + Paragraph *para; - get_cursor_pos(e->cursor_frame, e->cursor_para, - e->cursor_pos+e->cursor_trail, &x, &y, &h); + para = e->cursor_frame->paras[e->cursor_para]; + offs = pos_trail_to_offset(para, e->cursor_pos, e->cursor_trail); + get_cursor_pos(e->cursor_frame, e->cursor_para, offs, &x, &y, &h); /* Off the bottom? */ if ( y - e->scroll_pos + h > e->visible_height ) { @@ -637,14 +644,16 @@ static void insert_text(char *t, SCEditor *e) /* Is this paragraph even a text one? */ if ( para_type(para) == PARA_TYPE_TEXT ) { + size_t off; /* Yes. The "easy" case */ - insert_text_in_paragraph(para, e->cursor_pos+e->cursor_trail, - t); + off = pos_trail_to_offset(para, e->cursor_pos, e->cursor_trail); + insert_text_in_paragraph(para, off, t); wrap_paragraph(para, NULL, e->cursor_frame->w - e->cursor_frame->pad_l - e->cursor_frame->pad_r); if ( e->flow ) update_size(e); + cursor_moveh(e->cursor_frame, &e->cursor_para, &e->cursor_pos, &e->cursor_trail, +1); @@ -702,9 +711,15 @@ static void do_backspace(struct frame *fr, SCEditor *e) wrap_paragraph(e->cursor_frame->paras[new_para], NULL, wrapw); } else { - delete_text_in_paragraph(para, e->cursor_pos+e->cursor_trail, - old_pos+old_trail); + size_t offs_new, offs_old; + + offs_new = pos_trail_to_offset(para, e->cursor_pos, + e->cursor_trail); + offs_old = pos_trail_to_offset(para, old_pos, old_trail); + + delete_text_in_paragraph(para, offs_new, offs_old); wrap_paragraph(para, NULL, wrapw); + } @@ -1213,8 +1228,7 @@ static void copy_selection(SCEditor *e) char *storycode; SCBlock *bl; - bl = block_at_cursor(e->cursor_frame, e->cursor_para, - e->cursor_pos+e->cursor_trail); + bl = block_at_cursor(e->cursor_frame, e->cursor_para, 0); if ( bl == NULL ) return; storycode = serialise_sc_block(bl); @@ -1231,10 +1245,13 @@ static void paste_callback(GtkClipboard *cb, const gchar *text, void *vp) SCBlock *bl = sc_parse(text); SCBlock *cur_bl; size_t cur_sc_pos; + size_t offs; + Paragraph *para; + + para = e->cursor_frame->paras[e->cursor_para]; + offs = pos_trail_to_offset(para, e->cursor_pos, e->cursor_trail); - get_sc_pos(e->cursor_frame, e->cursor_para, - e->cursor_pos+e->cursor_trail, - &cur_bl, &cur_sc_pos); + get_sc_pos(e->cursor_frame, e->cursor_para, offs, &cur_bl, &cur_sc_pos); sc_insert_block(cur_bl, cur_sc_pos, bl); full_rerender(e); } |