aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2016-03-19 18:02:29 +0100
committerThomas White <taw@bitwiz.org.uk>2016-03-19 18:02:29 +0100
commit12e76ff1df47fa47a8b1458e4cacb309249737f2 (patch)
tree08d4ede966a8613f453db8eb30e37ed1f78f7541
parent17696106b37a1438845dc82fa2ec8734e92dafe2 (diff)
Deletion stuff
-rw-r--r--src/boxvec.c25
-rw-r--r--src/boxvec.h3
-rw-r--r--src/frame.c5
-rw-r--r--src/sc_editor.c85
-rw-r--r--src/wrap.c9
5 files changed, 96 insertions, 31 deletions
diff --git a/src/boxvec.c b/src/boxvec.c
index f00a81c..218dddb 100644
--- a/src/boxvec.c
+++ b/src/boxvec.c
@@ -26,6 +26,7 @@
#endif
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <assert.h>
@@ -75,6 +76,30 @@ int bv_add(struct boxvec *vec, struct wrap_box *bx)
}
+static int find_box(struct boxvec *vec, struct wrap_box *bx)
+{
+ int i = 0;
+ while ( (i<vec->n_boxes) && (vec->boxes[i] != bx) ) i++;
+ return i;
+}
+
+
+void bv_del(struct boxvec *vec, struct wrap_box *bx)
+{
+ int n = find_box(vec, bx);
+ if ( n == vec->n_boxes ) {
+ fprintf(stderr, "Couldn't find box to delete it!\n");
+ return;
+ }
+ assert(vec->boxes[n] == bx);
+ if ( n < vec->n_boxes-1 ) {
+ memmove(&vec->boxes[n], &vec->boxes[n+1],
+ (vec->n_boxes-n-1)*sizeof(struct wrap_box *));
+ }
+ vec->n_boxes--;
+}
+
+
struct wrap_box *bv_box(struct boxvec *vec, int i)
{
assert(vec != NULL);
diff --git a/src/boxvec.h b/src/boxvec.h
index e830837..259df89 100644
--- a/src/boxvec.h
+++ b/src/boxvec.h
@@ -53,6 +53,9 @@ extern int bv_ensure_space(struct boxvec *vec, int n);
/* Add to a bxvec or boxvec */
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);
+
/* 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/frame.c b/src/frame.c
index 5b932e6..7f41a41 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -66,6 +66,11 @@ struct frame *frame_new()
n->num_children = 0;
n->scblocks = NULL;
+ n->n_paragraphs = 0;
+ n->paragraphs = NULL;
+ n->paragraph_start_lines = NULL;
+ n->lines = NULL;
+ n->n_lines = 0;
n->boxes = bv_new();
diff --git a/src/sc_editor.c b/src/sc_editor.c
index 2e00e10..278f38f 100644
--- a/src/sc_editor.c
+++ b/src/sc_editor.c
@@ -807,22 +807,6 @@ void insert_scblock(SCBlock *scblock, SCEditor *e)
}
-/* The StoryCode for this box on this line in this frame has changed.
- * Update the boxes from the StoryCode */
-static void update_local(SCEditor *e, struct frame *fr, int line, int bn)
-{
- struct wrap_box *box = bv_box(fr->lines[line].boxes, bn);
-
- shape_box(box);
-
- /* Wrap the paragraph again */
- wrap_contents(fr); /* FIXME: Only the current paragraph */
- update_size(e);
-
- sc_editor_redraw(e);
-}
-
-
static void shift_box_offsets(struct frame *fr, struct wrap_box *box, int n)
{
int i;
@@ -893,7 +877,6 @@ static void insert_text(char *t, SCEditor *e)
int sln, sbx, sps;
struct wrap_box *sbox;
struct frame *fr = e->cursor_frame;
- int err = 0;
printf("insert! --------------------------------------------------------\n");
@@ -940,10 +923,10 @@ static void insert_text(char *t, SCEditor *e)
fr->empty = 0;
- update_local(e, fr, sln, sbx);
-
+ wrap_contents(e->cursor_frame);
+ update_size(e);
fixup_cursor(e);
- printf("done! --------------------------------------------------------\n");
+ printf("done! -----------------------------------------------------\n");
advance_cursor(e);
@@ -953,8 +936,7 @@ static void insert_text(char *t, SCEditor *e)
static void do_backspace(struct frame *fr, SCEditor *e)
{
- int sln, sbx, sps, sseg;
- int err = 0;
+ int sln, sbx, sps;
if ( fr == NULL ) return;
@@ -965,10 +947,6 @@ static void do_backspace(struct frame *fr, SCEditor *e)
sbx = e->cursor_box;
sps = e->cursor_pos;
struct wrap_box *sbox = bv_box(e->cursor_frame->lines[sln].boxes, sbx);
- sseg = which_segment(sbox, sps, &err);
- if ( err ) return;
-
- cur_box_diag(e);
move_cursor_back(e);
@@ -980,13 +958,58 @@ static void do_backspace(struct frame *fr, SCEditor *e)
sc_delete_text(fbox->scblock, e->cursor_pos+fbox->offs_char,
sbox->scblock, sps+sbox->offs_char);
- /* Tweak the offsets of all the subsequent boxes */
- shift_box_offsets(fr, sbox, -1);
- sbox->len_chars -= 1;
- sbox->segs[sseg].len_chars -= 1;
+ if ( (sps == 0) && (fbox->space == WRAP_SPACE_INTERWORD) ) {
+
+ /* We are deleting an interword space.
+ * It's enough just to change the space type, and leave two
+ * boxes butted up with no space. */
+ fbox->space = WRAP_SPACE_NONE;
+ shift_box_offsets(fr, fbox, -1);
+ itemize_and_shape(fbox, e->pc);
- update_local(e, fr, sln, sbx);
+ } else if ( (sps == 0) && (fbox->space == WRAP_SPACE_NONE) ) {
+ /* We are deleting across a box boundary, but there is no
+ * space to delete */
+ if ( fbox->len_chars == 0 ) {
+ printf("Deleting a zero-length box\n");
+ } else {
+ fbox->len_chars -= 1;
+ shift_box_offsets(fr, fbox, -1);
+ itemize_and_shape(fbox, e->pc);
+ }
+
+ } else if ( (sps == 0) && (fbox->space == WRAP_SPACE_EOP) ) {
+
+ /* We are deleting the newline between paragraphs */
+ fbox->space = WRAP_SPACE_NONE;
+ shift_box_offsets(fr, fbox, -1);
+ itemize_and_shape(fbox, e->pc);
+
+ } else {
+
+ sbox->len_chars -= 1;
+ shift_box_offsets(fr, sbox, -1);
+ if ( sbox->len_chars == 0 ) {
+
+ if ( sbox->space == WRAP_SPACE_NONE ) {
+ printf("deleting box.\n");
+ bv_del(e->cursor_frame->boxes, sbox);
+ free(sbox);
+ } else {
+ printf("downgrading box.\n");
+ sbox->type = WRAP_BOX_NOTHING;
+ sbox->width = 0;
+ }
+
+ } else {
+ itemize_and_shape(sbox, e->pc);
+ }
+
+ }
+
+ wrap_contents(e->cursor_frame);
+ update_size(e);
fixup_cursor(e);
cur_box_diag(e);
sc_editor_redraw(e);
diff --git a/src/wrap.c b/src/wrap.c
index 6389905..8918bc9 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -921,6 +921,15 @@ int wrap_contents(struct frame *fr)
fr->trouble = 0;
alloc_lines(fr);
+ for ( i=0; i<fr->n_paragraphs; i++ ) {
+ bv_free(fr->paragraphs[i]);
+ }
+ free(fr->paragraphs);
+ free(fr->paragraph_start_lines);
+ for ( i=0; i<fr->n_lines; i++ ) {
+ wrap_line_free(&fr->lines[i]);
+ }
+
/* Split text into paragraphs */
i = 0;
fr->n_paragraphs = 0;