aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2016-03-29 22:56:07 +0200
committerThomas White <taw@bitwiz.org.uk>2016-03-29 22:56:07 +0200
commitc56a39fc9bda020f6c5c862bcf7c9455e0d83459 (patch)
treef830f6bbe42708e7fa2f4383371830c0951488d7
parentd7ee6bba4f775abb09836cddf1dd6a7cda5f04db (diff)
Enable text insertion
-rw-r--r--src/frame.c61
-rw-r--r--src/frame.h3
-rw-r--r--src/sc_editor.c14
-rw-r--r--src/sc_parse.c4
-rw-r--r--src/sc_parse.h2
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 = &para->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 = &para->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);