From 49bdd47afa1c174c751532dc8a5f01dd8d27914e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 13 Sep 2016 10:05:10 +0200 Subject: Implement multi-run deletion --- src/frame.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'src/frame.c') diff --git a/src/frame.c b/src/frame.c index fbb67e8..9b71a02 100644 --- a/src/frame.c +++ b/src/frame.c @@ -800,10 +800,8 @@ void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t) void delete_text_in_paragraph(Paragraph *para, size_t offs1, size_t offs2) { - int nrun1, nrun2; + int nrun1, nrun2, nrun; int i; - struct text_run *run1; - struct text_run *run2; size_t scblock_offs1, scblock_offs2; /* Find which run we are in */ @@ -813,27 +811,39 @@ void delete_text_in_paragraph(Paragraph *para, size_t offs1, size_t offs2) fprintf(stderr, "Couldn't find run to delete from.\n"); return; } - run1 = ¶->runs[nrun1]; - run2 = ¶->runs[nrun2]; - - /* Translate paragraph offsets into SCBlock offsets */ - scblock_offs1 = offs1 - run1->para_offs_bytes + run1->scblock_offs_bytes; - scblock_offs2 = offs2 - run2->para_offs_bytes + run2->scblock_offs_bytes; - sc_delete_text(run1->scblock, scblock_offs1, - run2->scblock, scblock_offs2); - - if ( nrun1 == nrun2 ) { - size_t del_len = offs2 - offs1; - run1->len_bytes -= del_len; - for ( i=nrun1+1; in_runs; i++ ) { - if ( para->runs[i].scblock == run1->scblock ) { + + for ( nrun=nrun1; nrun<=nrun2; nrun++ ) { + + ssize_t ds, de; + struct text_run *run; + + run = ¶->runs[nrun]; + ds = offs1 - run->para_offs_bytes; + de = offs2 - run->para_offs_bytes; + if ( ds < 0 ) ds = 0; + if ( de > run->len_bytes ) { + de = run->len_bytes; + } + assert(ds >= 0); /* Otherwise nrun1 was too big */ + assert(de >= 0); /* Otherwise nrun2 was too big */ + if ( ds == de ) continue; + + /* Delete from the corresponding SC block */ + scblock_offs1 = ds + run->scblock_offs_bytes; + scblock_offs2 = de + run->scblock_offs_bytes; + sc_delete_text(run->scblock, scblock_offs1, + run->scblock, scblock_offs2); + + /* Fix up the offsets of the subsequent text runs */ + size_t del_len = de - ds; + run->len_bytes -= del_len; + for ( i=nrun+1; in_runs; i++ ) { + if ( para->runs[i].scblock == run->scblock ) { para->runs[i].scblock_offs_bytes -= del_len; } para->runs[i].para_offs_bytes -= del_len; } - } else { - /* FIXME: Implement this case */ - printf("Multi-run delete!\n"); + } } -- cgit v1.2.3