From f6f225c85e8c252623af5f0a5fb1460707c8fc4b Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 30 Jun 2014 23:53:25 +0200 Subject: Mostly fix cursor stuff --- src/mainwindow.c | 44 +++++++++++++--------------- src/shape.c | 5 ++-- src/wrap.c | 88 ++++++++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 91 insertions(+), 46 deletions(-) diff --git a/src/mainwindow.c b/src/mainwindow.c index eb94019..8133d91 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -1088,17 +1088,26 @@ static void move_cursor(struct presentation *p, signed int x, signed int y) cb = p->cursor_box; cl = p->cursor_line; - if ( box->type == WRAP_BOX_PANGO ) { + switch ( box->type ) { + case WRAP_BOX_PANGO: if ( cp+1 > box->len_chars ) { advance = 1; } else { cp++; } + break; - } else { + case WRAP_BOX_NOTHING: + case WRAP_BOX_SENTINEL: + advance = 1; + break; + + case WRAP_BOX_IMAGE: cp++; if ( cp > 1 ) advance = 1; + break; + } if ( advance ) { @@ -1114,16 +1123,14 @@ static void move_cursor(struct presentation *p, signed int x, signed int y) /* Give up - could not move */ return; } - p->cursor_line = cl; line = &p->cursor_frame->lines[cl]; cb = 0; cp = 0; } - } while ( (line->boxes[cb].type == WRAP_BOX_SENTINEL) - || (line->boxes[cb].type == WRAP_BOX_NOTHING) - || !line->boxes[cb].editable ); + } while ( !line->boxes[cb].editable ); + p->cursor_line = cl; p->cursor_box = cb; } @@ -1140,7 +1147,6 @@ static void insert_text(char *t, struct presentation *p) int sln, sbx, sps; struct wrap_box *sbox; struct frame *fr = p->cursor_frame; - SCBlock *iblock; if ( fr == NULL ) return; @@ -1152,18 +1158,10 @@ static void insert_text(char *t, struct presentation *p) sps = p->cursor_pos; sbox = &p->cursor_frame->lines[sln].boxes[sbx]; - printf("%i/%i/%i\n", sln, sbx, sps); - printf("frame has %i lines\n", fr->n_lines); - - if ( sln >= fr->n_lines ) { - iblock = fr->scblocks; - printf("block %p\n", iblock); - } else { - iblock = sbox->scblock; - printf("line has %i boxes\n", - p->cursor_frame->lines[sln].n_boxes); - } - sc_insert_text(iblock, sps+sbox->offs_char, t); + cur_box_diag(p); + printf("inserting block=%p, offset %i+%i, '%s'\n", + sbox->scblock, sps, sbox->offs_char, t); + sc_insert_text(sbox->scblock, sps+sbox->offs_char, t); move_cursor(p, +1, 0); rerender_slide(p); @@ -1183,15 +1181,13 @@ static void do_backspace(struct frame *fr, struct presentation *p) sln = p->cursor_line; sbx = p->cursor_box; sps = p->cursor_pos; + struct wrap_box *sbox = &p->cursor_frame->lines[sln].boxes[sbx]; - printf("%i/%i/%i\n", sln, sbx, sps); - printf("frame has %i lines\n", fr->n_lines); - printf("line has %i boxes\n", p->cursor_frame->lines[sln].n_boxes); - + cur_box_diag(p); move_cursor_back(p); + cur_box_diag(p); /* Delete may cross wrap boxes and maybe SCBlock boundaries */ - struct wrap_box *sbox = &p->cursor_frame->lines[sln].boxes[sbx]; struct wrap_line *fline = &p->cursor_frame->lines[p->cursor_line]; struct wrap_box *fbox = &fline->boxes[p->cursor_box]; diff --git a/src/shape.c b/src/shape.c index 8ae41ec..97178a1 100644 --- a/src/shape.c +++ b/src/shape.c @@ -209,6 +209,8 @@ int split_words(struct wrap_line *boxes, PangoContext *pc, SCBlock *bl, } } + + /* Add the stuff left over at the end */ if ( i > start ) { size_t l = strlen(text+start); @@ -219,9 +221,6 @@ int split_words(struct wrap_line *boxes, PangoContext *pc, SCBlock *bl, add_wrap_boxes(boxes, text, WRAP_SPACE_EOP, pc, scin, bl, start, l-1, editable); - //add_wrap_boxes(boxes, "", - // WRAP_SPACE_NONE, pc, scin, bl, start+l, - // 1, editable); } else { diff --git a/src/wrap.c b/src/wrap.c index d887c7b..d58cce2 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -209,9 +209,7 @@ void move_cursor_back(struct presentation *p) cb = line->n_boxes - 1; } - } while ( (line->boxes[cb].type == WRAP_BOX_SENTINEL) - || (line->boxes[cb].type == WRAP_BOX_NOTHING) - || !line->boxes[cb].editable ); + } while ( !line->boxes[cb].editable ); p->cursor_box = cb; box = &line->boxes[cb]; @@ -310,11 +308,13 @@ void find_cursor(struct frame *fr, double xposd, double yposd, switch ( b->type ) { - case WRAP_BOX_NOTHING : - fprintf(stderr, "Clicked a nothing box!\n"); - abort(); + case WRAP_BOX_NOTHING: + case WRAP_BOX_SENTINEL: + case WRAP_BOX_IMAGE: + offs = 0; + break; - case WRAP_BOX_PANGO : + case WRAP_BOX_PANGO: x_pos_i = pango_units_from_double(x_pos); block_text = sc_block_contents(b->scblock); box_text = g_utf8_offset_to_pointer(block_text, b->offs_char); @@ -326,14 +326,6 @@ void find_cursor(struct frame *fr, double xposd, double yposd, offs = idx + trail; break; - case WRAP_BOX_SENTINEL : - offs = 0; - break; - - default : - offs = 0; - break; - } *pos = offs; @@ -781,7 +773,8 @@ void wrap_line_free(struct wrap_line *l) } -static struct wrap_line *split_paragraph(struct wrap_line *boxes, int *n) +static struct wrap_line *split_paragraph(struct wrap_line *boxes, int *n, + int *eop) { int i; int start = *n; @@ -789,8 +782,10 @@ static struct wrap_line *split_paragraph(struct wrap_line *boxes, int *n) if ( start >= boxes->n_boxes ) return NULL; + *eop = 0; for ( i=start; in_boxes; i++ ) { if ( boxes->boxes[i].space == WRAP_SPACE_EOP ) { + *eop = 1; break; } } @@ -847,7 +842,7 @@ void show_boxes(struct wrap_line *boxes) int wrap_contents(struct frame *fr) { struct wrap_line *para; - int i; + int i, eop = 0; const double rho = 2.0; const double wrap_w = fr->w - fr->pad_l - fr->pad_r; @@ -862,7 +857,7 @@ int wrap_contents(struct frame *fr) i = 0; do { - para = split_paragraph(fr->boxes, &i); + para = split_paragraph(fr->boxes, &i, &eop); /* Split paragraphs into lines */ if ( para != NULL ) { @@ -877,7 +872,62 @@ int wrap_contents(struct frame *fr) } while ( para != NULL ); for ( i=0; in_lines; i++ ) { - distribute_spaces(&fr->lines[i], wrap_w, rho); + + struct wrap_line *line = &fr->lines[i]; + + distribute_spaces(line, wrap_w, rho); + + /* Strip any sentinel boxes added by the wrapping algorithm */ + if ( line->boxes[line->n_boxes-1].type == WRAP_BOX_SENTINEL ) { + line->n_boxes--; + } + + } + + /* If the last paragraph ended with an EOP, add an extra line */ + printf("Done. eop=%i\n", eop); + if ( eop || (fr->n_lines == 0) ) { + + struct wrap_line *l; + struct wrap_box *last_box; + + if ( fr->n_lines > 0 ) { + l = &fr->lines[fr->n_lines-1]; + last_box = &l->boxes[l->n_boxes-1]; + } else { + last_box = NULL; + } + + if ( fr->n_lines + 1 > fr->max_lines ) { + fr->max_lines += 32; + alloc_lines(fr); + if ( fr->n_lines == fr->max_lines ) return 1; + } + + l = &fr->lines[fr->n_lines]; + fr->n_lines++; + initialise_line(l); + + l->max_boxes = 1; + alloc_boxes(l); + l->n_boxes = 1; + l->boxes[0].type = WRAP_BOX_NOTHING; + l->boxes[0].editable = 1; + l->boxes[0].space = WRAP_SPACE_NONE; + + if ( last_box != NULL ) { + l->boxes[0].scblock = last_box->scblock; + l->boxes[0].offs_char = last_box->len_chars + + last_box->offs_char + 1; + l->boxes[0].ascent = last_box->ascent; + l->boxes[0].height = last_box->height; + l->boxes[0].width = 0; + /* FIXME: Get ascent and descent from font metrics for + * whichever font will be used in this box */ + } + } + + for ( i=0; in_lines; i++ ) { calc_line_geometry(&fr->lines[i]); } -- cgit v1.2.3