diff options
author | Thomas White <taw@bitwiz.org.uk> | 2016-03-29 22:56:07 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2016-03-29 22:56:07 +0200 |
commit | c56a39fc9bda020f6c5c862bcf7c9455e0d83459 (patch) | |
tree | f830f6bbe42708e7fa2f4383371830c0951488d7 /src | |
parent | d7ee6bba4f775abb09836cddf1dd6a7cda5f04db (diff) |
Enable text insertion
Diffstat (limited to 'src')
-rw-r--r-- | src/frame.c | 61 | ||||
-rw-r--r-- | src/frame.h | 3 | ||||
-rw-r--r-- | src/sc_editor.c | 14 | ||||
-rw-r--r-- | src/sc_parse.c | 4 | ||||
-rw-r--r-- | src/sc_parse.h | 2 |
5 files changed, 77 insertions, 7 deletions
diff --git a/src/frame.c b/src/frame.c index b021b42..1fb10c6 100644 --- a/src/frame.c +++ b/src/frame.c @@ -38,7 +38,8 @@ struct text_run { SCBlock *scblock; - size_t offs_bytes; + size_t scblock_offs_bytes; + size_t para_offs_bytes; size_t len_bytes; PangoFontDescription *fontdesc; double col[4]; @@ -61,6 +62,7 @@ struct _paragraph struct text_run *runs; int open; PangoLayout *layout; + size_t offset_last; /* For PARA_TYPE_IMAGE */ char *filename; @@ -302,7 +304,7 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w) guint16 r, g, b; run_text = sc_block_contents(para->runs[i].scblock) - + para->runs[i].offs_bytes; + + para->runs[i].scblock_offs_bytes; attr = pango_attr_font_desc_new(para->runs[i].fontdesc); attr->start_index = pos; @@ -355,7 +357,9 @@ void add_run(Paragraph *para, SCBlock *scblock, size_t offs_bytes, para->runs = runs_new; para->runs[para->n_runs].scblock = scblock; - para->runs[para->n_runs].offs_bytes = offs_bytes; + para->runs[para->n_runs].scblock_offs_bytes = offs_bytes; + para->runs[para->n_runs].para_offs_bytes = para->offset_last; + para->offset_last += len_bytes; para->runs[para->n_runs].len_bytes = len_bytes; para->runs[para->n_runs].fontdesc = pango_font_description_copy(fdesc); para->runs[para->n_runs].col[0] = col[0]; @@ -458,6 +462,7 @@ Paragraph *last_open_para(struct frame *fr) pnew->runs = NULL; pnew->layout = NULL; pnew->height = 0.0; + pnew->offset_last = 0; return pnew; } @@ -678,3 +683,53 @@ void check_callback_click(struct frame *fr, int para) p->click_func(0.0, 0.0, p->bvp, p->vp); } } + + +static int which_run(Paragraph *para, size_t offs) +{ + int i; + + for ( i=0; i<para->n_runs; i++ ) { + struct text_run *run = ¶->runs[i]; + if ( (offs >= run->para_offs_bytes) + && (offs < run->para_offs_bytes + run->len_bytes) ) + { + return i; + } + } + return para->n_runs; +} + + +void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t) +{ + int nrun; + int i; + struct text_run *run; + size_t run_offs, scblock_offs, ins_len; + + /* Find which run we are in */ + nrun = which_run(para, offs); + if ( nrun == para->n_runs ) { + fprintf(stderr, "Couldn't find run to insert into.\n"); + return; + } + run = ¶->runs[nrun]; + + /* Translate paragraph offset for insertion into SCBlock offset */ + run_offs = offs - run->para_offs_bytes; + scblock_offs = run_offs + run->scblock_offs_bytes; + sc_insert_text(run->scblock, scblock_offs, t); + + /* Update length of this run */ + ins_len = strlen(t); + run->len_bytes += ins_len; + + /* Update offsets of subsequent runs */ + for ( i=nrun+1; i<para->n_runs; i++ ) { + if ( para->runs[i].scblock == run->scblock ) { + para->runs[i].scblock_offs_bytes += ins_len; + } + para->runs[i].para_offs_bytes += ins_len; + } +} diff --git a/src/frame.h b/src/frame.h index f61f414..50fdaca 100644 --- a/src/frame.h +++ b/src/frame.h @@ -144,4 +144,7 @@ extern void cursor_movev(struct frame *fr, int *cpara, int *cpos, int *ctrail, extern void check_callback_click(struct frame *fr, int para); +extern void insert_text_in_paragraph(Paragraph *para, size_t offs, + const char *t); + #endif /* FRAME_H */ diff --git a/src/sc_editor.c b/src/sc_editor.c index 6c6c281..72e90e8 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -581,7 +581,19 @@ void insert_scblock(SCBlock *scblock, SCEditor *e) static void insert_text(char *t, SCEditor *e) { - /* FIXME: Insert "t" at the cursor */ + Paragraph *para; + + if ( e->cursor_para >= e->cursor_frame->n_paras ) { + fprintf(stderr, "Cursor paragraph number is too high!\n"); + return; + } + + para = e->cursor_frame->paras[e->cursor_para]; + insert_text_in_paragraph(para, e->cursor_pos+e->cursor_trail, t); + wrap_paragraph(para, NULL, e->cursor_frame->w - e->cursor_frame->pad_l + - e->cursor_frame->pad_r); + cursor_moveh(e->cursor_frame, &e->cursor_para, + &e->cursor_pos, &e->cursor_trail, +1); sc_editor_redraw(e); } diff --git a/src/sc_parse.c b/src/sc_parse.c index 60a03ff..95b5c76 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -554,7 +554,7 @@ SCBlock *find_last_child(SCBlock *bl) } -void sc_insert_text(SCBlock *b1, int o1, const char *t) +void sc_insert_text(SCBlock *b1, size_t o1, const char *t) { if ( b1->contents == NULL ) { b1->contents = strdup(t); @@ -563,7 +563,7 @@ void sc_insert_text(SCBlock *b1, int o1, const char *t) size_t len = strlen(b1->contents)+1+strlen(t); char *cnew = realloc(b1->contents, len); char *tmp = malloc(len); - char *p1 = g_utf8_offset_to_pointer(cnew, o1); + char *p1 = cnew + o1; if ( (cnew == NULL) || (tmp == NULL) ) return; strcpy(tmp, p1); strcpy(p1, t); diff --git a/src/sc_parse.h b/src/sc_parse.h index b1b59dd..94bab30 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -63,7 +63,7 @@ extern SCBlock *find_last_child(SCBlock *bl); extern void sc_block_set_options(SCBlock *bl, char *opt); extern void sc_block_set_contents(SCBlock *bl, char *con); -extern void sc_insert_text(SCBlock *b1, int o1, const char *t); +extern void sc_insert_text(SCBlock *b1, size_t o1, const char *t); extern void sc_insert_block(SCBlock *b1, int o1, SCBlock *ins); extern void sc_delete_text(SCBlock *b1, int o1, SCBlock *b2, int o2); |