diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/frame.c | 77 | ||||
-rw-r--r-- | src/frame.h | 2 | ||||
-rw-r--r-- | src/sc_editor.c | 4 | ||||
-rw-r--r-- | src/sc_parse.c | 33 | ||||
-rw-r--r-- | src/sc_parse.h | 3 |
5 files changed, 104 insertions, 15 deletions
diff --git a/src/frame.c b/src/frame.c index fce039d..f275baf 100644 --- a/src/frame.c +++ b/src/frame.c @@ -829,13 +829,38 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, size_t offs2) } -static void split_text_paragraph(struct frame *fr, int pn, int pos, +static __attribute__((unused)) void show_para(Paragraph *p) +{ + int i; + printf("Paragraph %p\n", p); + printf("%i runs:\n", p->n_runs); + for ( i=0; i<p->n_runs; i++ ) { + printf(" Run %2i: para offs %lli, SCBlock %p offs %lli, len " + "%lli %s\n", i, (long long int)p->runs[i].para_offs_bytes, + p->runs[i].scblock, + (long long int)p->runs[i].scblock_offs_bytes, + (long long int)p->runs[i].len_bytes, + pango_font_description_to_string(p->runs[i].fontdesc)); + } +} + + +static char *s_strdup(const char *a) +{ + if ( a == NULL ) return NULL; + return strdup(a); +} + + +static void split_text_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc) { Paragraph *pnew; - int i, j; + int i; + size_t offs, run_offs; int run; Paragraph *para = fr->paras[pn]; + struct text_run *rr; pnew = insert_paragraph(fr, pn); if ( pnew == NULL ) { @@ -855,25 +880,55 @@ static void split_text_paragraph(struct frame *fr, int pn, int pos, return; /* Badness is coming */ } - /* If the position is right at the start of a run, the whole run - * gets moved to the next paragraph */ - if ( para->runs[run].para_offs_bytes ) { - } + /* First run of the new paragraph contains the leftover text */ + rr = ¶->runs[run]; + pnew->runs[0].scblock = rr->scblock; + run_offs = pos - rr->para_offs_bytes; + pnew->runs[0].scblock_offs_bytes = rr->scblock_offs_bytes + run_offs; + pnew->runs[0].para_offs_bytes = 0; + pnew->runs[0].len_bytes = rr->len_bytes - run_offs; + pnew->runs[0].col[0] = rr->col[0]; + pnew->runs[0].col[1] = rr->col[1]; + pnew->runs[0].col[2] = rr->col[2]; + pnew->runs[0].col[3] = rr->col[3]; + pnew->runs[0].fontdesc = pango_font_description_copy(rr->fontdesc); + pnew->n_runs = 1; + + /* All later runs just get moved to the new paragraph */ + offs = pnew->runs[0].len_bytes; + for ( i=run+1; i<para->n_runs; i++ ) { + pnew->runs[pnew->n_runs] = para->runs[i]; + pnew->runs[pnew->n_runs].para_offs_bytes = offs; + pnew->n_runs++; + offs += rr->len_bytes; + } + + /* Truncate the first paragraph at the appropriate position */ + rr->len_bytes = run_offs; + para->n_runs = run+1; - j = 0; - for ( i=run; i<para->n_runs; i++ ) { - pnew->runs[j++] = para->runs[i]; + /* If the first and second paragraphs have the same SCBlock, split it */ + if ( rr->scblock == pnew->runs[0].scblock ) { + size_t sc_offs; + sc_offs = rr->scblock_offs_bytes + run_offs; + pnew->runs[0].scblock = sc_block_split(rr->scblock, sc_offs); + pnew->runs[0].scblock_offs_bytes = 0; } + /* Add a newline after the end of the first paragraph's SC */ + sc_block_append(rr->scblock, s_strdup(sc_block_name(rr->scblock)), + s_strdup(sc_block_options(rr->scblock)), + strdup("\n"), NULL); + + pnew->open = para->open; para->open = 0; - para->n_runs = run+1; wrap_paragraph(para, pc, fr->w); wrap_paragraph(pnew, pc, fr->w); } -void split_paragraph(struct frame *fr, int pn, int pos, PangoContext *pc) +void split_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc) { Paragraph *para = fr->paras[pn]; diff --git a/src/frame.h b/src/frame.h index 5c7abc2..a480938 100644 --- a/src/frame.h +++ b/src/frame.h @@ -150,7 +150,7 @@ extern void insert_text_in_paragraph(Paragraph *para, size_t offs, extern void delete_text_in_paragraph(Paragraph *para, size_t offs1, size_t offs2); -extern void split_paragraph(struct frame *fr, int pn, int pos, +extern void split_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc); #endif /* FRAME_H */ diff --git a/src/sc_editor.c b/src/sc_editor.c index 0db20a8..fac8210 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -557,11 +557,11 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, SCEditor *e) void split_paragraph_at_cursor(SCEditor *e) { - split_paragraph(e->cursor_frame, e->cursor_para, e->cursor_pos, e->pc); + split_paragraph(e->cursor_frame, e->cursor_para, + e->cursor_pos+e->cursor_trail, e->pc); } - static void insert_text(char *t, SCEditor *e) { Paragraph *para; diff --git a/src/sc_parse.c b/src/sc_parse.c index edad176..c8eea6f 100644 --- a/src/sc_parse.c +++ b/src/sc_parse.c @@ -103,6 +103,7 @@ SCBlock *sc_block_append(SCBlock *bl, char *name, char *opt, char *contents, bln->next = NULL; if ( bl != NULL ) { + bln->next = bl->next; bl->next = bln; } @@ -124,6 +125,7 @@ SCBlock *sc_block_append_end(SCBlock *bl, char *name, char *opt, char *contents) if ( bln == NULL ) return NULL; while ( bl->next != NULL ) { + bln->next = bl->next; bl = bl->next; }; @@ -659,3 +661,34 @@ SCBlock *sc_block_copy(const SCBlock *bl) return first_copy; } + + +static char *s_strdup(const char *a) +{ + if ( a == NULL ) return NULL; + return strdup(a); +} + + +SCBlock *sc_block_split(SCBlock *bl, size_t pos) +{ + SCBlock *n = sc_block_new(); + + if ( bl->child != NULL ) { + fprintf(stderr, "Splitting a block with a child!\n"); + return NULL; + } + + /* Second block */ + n->name = s_strdup(bl->name); + n->options = s_strdup(bl->options); + n->contents = strdup(bl->contents+pos); + + /* Truncate the first block */ + bl->contents[pos] = '\0'; + + n->next = bl->next; + bl->next = n; + + return n; +} diff --git a/src/sc_parse.h b/src/sc_parse.h index 94bab30..dad797b 100644 --- a/src/sc_parse.h +++ b/src/sc_parse.h @@ -1,7 +1,7 @@ /* * sc_parse.h * - * Copyright © 2013-2015 Thomas White <taw@bitwiz.org.uk> + * Copyright © 2013-2016 Thomas White <taw@bitwiz.org.uk> * * This file is part of Colloquium. * @@ -66,6 +66,7 @@ extern void sc_block_set_contents(SCBlock *bl, char *con); 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); +extern SCBlock *sc_block_split(SCBlock *bl, size_t pos); extern void show_sc_blocks(const SCBlock *bl); extern void show_sc_block(const SCBlock *bl, const char *prefix); |