diff options
author | Thomas White <taw@bitwiz.org.uk> | 2016-03-20 17:20:23 +0100 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2016-03-20 17:20:23 +0100 |
commit | 1ee3354534505a62a28a8aa9ee927ae91cc6e3ec (patch) | |
tree | 5db8bc161d2e77f68d2c88534087c453afe5af62 /src | |
parent | 44e484efec8838a3a0da0b88207d84939226d165 (diff) |
Line break on editing
Diffstat (limited to 'src')
-rw-r--r-- | src/boxvec.c | 24 | ||||
-rw-r--r-- | src/boxvec.h | 4 | ||||
-rw-r--r-- | src/sc_editor.c | 64 |
3 files changed, 76 insertions, 16 deletions
diff --git a/src/boxvec.c b/src/boxvec.c index 218dddb..e065a91 100644 --- a/src/boxvec.c +++ b/src/boxvec.c @@ -100,6 +100,30 @@ void bv_del(struct boxvec *vec, struct wrap_box *bx) } +int bv_add_after(struct boxvec *vec, struct wrap_box *bx, struct wrap_box *add) +{ + int n = find_box(vec, bx); + if ( n == vec->n_boxes ) { + fprintf(stderr, "Couldn't find box to add after!\n"); + return 1; + } + assert(vec->boxes[n] == bx); + + n++; + bv_ensure_space(vec, vec->n_boxes+1); + + if ( n < vec->n_boxes-1 ) { + memmove(&vec->boxes[n+1], &vec->boxes[n], + (vec->n_boxes-n)*sizeof(struct wrap_box *)); + } /* otherwise there's nothing to move */ + + vec->boxes[n] = add; + vec->n_boxes++; + + return 0; +} + + struct wrap_box *bv_box(struct boxvec *vec, int i) { assert(vec != NULL); diff --git a/src/boxvec.h b/src/boxvec.h index 259df89..9538a35 100644 --- a/src/boxvec.h +++ b/src/boxvec.h @@ -56,6 +56,10 @@ extern int bv_add(struct boxvec *vec, struct wrap_box *bx); /* (Find and then) delete a box from a boxvec */ extern void bv_del(struct boxvec *vec, struct wrap_box *bx); +/* Add a new box after the specified one */ +extern int bv_add_after(struct boxvec *vec, struct wrap_box *bx, + struct wrap_box *add); + /* Get a box from a boxvec or bxvec */ extern struct wrap_box *bv_box(struct boxvec *vec, int i); extern struct wrap_box *bv_last(struct boxvec *vec); diff --git a/src/sc_editor.c b/src/sc_editor.c index 2c11c67..9509e6a 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -827,44 +827,76 @@ static void shift_box_offsets(struct frame *fr, struct wrap_box *box, int n) } -static void fixup_line_breaks(struct wrap_box *sbox, struct wrap_line *line, - int sbx, int cursor_pos, PangoLanguage *lang) +static void fixup_line_breaks(struct wrap_box *sbox, struct boxvec *boxes, + int cursor_pos, PangoLanguage *lang, + PangoContext *pc) { const char *text; size_t len_bytes; int len_chars; PangoLogAttr *log_attrs; int offs; - return; /* FIXME ! */ + /* Run pango_get_log_attrs on the entire SCBlock, to get good context */ text = sc_block_contents(sbox->scblock); len_bytes = strlen(text); len_chars = g_utf8_strlen(text, -1); + if ( len_chars <= 1 ) return; log_attrs = malloc((len_chars+1)*sizeof(PangoLogAttr)); if ( log_attrs == NULL ) return; pango_get_log_attrs(text, len_bytes, -1, lang, log_attrs, len_chars+1); + /* Take a peek at the situation near where we just typed */ offs = sbox->offs_char + cursor_pos; - - if ( (len_chars > 1) && log_attrs[offs+1].is_line_break ) { + if ( log_attrs[offs+1].is_line_break ) { struct wrap_box *nbox; - printf("Adding line break (new box)\n"); + printf("Adding line break (new box) at pos %i\n", offs); + printf("offset %i into box\n", cursor_pos); /* Add a new box containing the text after the break */ - insert_box(line, sbx); - nbox = bv_box(line->boxes, sbx); + nbox = calloc(1, sizeof(struct wrap_box)); + if ( nbox == NULL ) { + fprintf(stderr, "Failed to allocate a text box.\n"); + return; + } + bv_add_after(boxes, sbox, nbox); nbox->type = WRAP_BOX_PANGO; - nbox->space = WRAP_SPACE_INTERWORD; - nbox->len_chars = cursor_pos; + nbox->space = sbox->space; + nbox->len_chars = sbox->len_chars - cursor_pos; + nbox->offs_char = sbox->offs_char + cursor_pos; + nbox->scblock = sbox->scblock; + nbox->fontdesc = pango_font_description_copy(sbox->fontdesc); + nbox->col[0] = sbox->col[0]; + nbox->col[1] = sbox->col[1]; + nbox->col[2] = sbox->col[2]; + nbox->col[3] = sbox->col[3]; + nbox->editable = sbox->editable; /* Shorten the text in the first box */ - sbox->len_chars -= cursor_pos; + sbox->len_chars = cursor_pos; + if ( log_attrs[offs].is_expandable_space ) { + sbox->space = WRAP_SPACE_INTERWORD; + nbox->len_chars--; + nbox->offs_char++; + } else if ( log_attrs[offs+1].is_mandatory_break ) { + sbox->space = WRAP_SPACE_EOP; + printf("New paragraph!\n"); + nbox->offs_char++; + nbox->len_chars--; + } else { + sbox->space = WRAP_SPACE_NONE; + printf("two boxes.\n"); + } + + printf("boxes: <%i %i %i>[%i %i %i]\n", + sbox->offs_char, sbox->len_chars, sbox->n_segs, + nbox->offs_char, nbox->len_chars, nbox->n_segs); - shape_box(sbox); - //shape_box(nbox); + itemize_and_shape(nbox, pc); + /* sbox will get done in just a moment */ } @@ -914,13 +946,13 @@ static void insert_text(char *t, SCEditor *e) /* Tweak the offsets of all the subsequent boxes */ shift_box_offsets(fr, sbox, 1); + fixup_line_breaks(sbox, e->cursor_frame->boxes, e->cursor_pos, + e->lang, e->pc); + /* The box must be analysed by Pango again, because the segments * might have changed */ itemize_and_shape(sbox, e->pc); - fixup_line_breaks(sbox, &e->cursor_frame->lines[sln], sbx, - e->cursor_pos, e->lang); - fr->empty = 0; wrap_contents(e->cursor_frame); |