diff options
author | Thomas White <taw@bitwiz.org.uk> | 2013-02-20 00:22:52 +0100 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2013-02-20 00:22:52 +0100 |
commit | 59c7b765c44ee2ae3e81366bea2fc149e2466d13 (patch) | |
tree | a88d6c5262503330da1785542a9ed0f44be80392 | |
parent | ecb437e07db5d0edc3ee57f682b277ab8238537b (diff) |
(Very) basic text editing
-rw-r--r-- | src/frame.h | 36 | ||||
-rw-r--r-- | src/mainwindow.c | 62 | ||||
-rw-r--r-- | src/presentation.h | 1 | ||||
-rw-r--r-- | src/render.c | 93 |
4 files changed, 125 insertions, 67 deletions
diff --git a/src/frame.h b/src/frame.h index dbb7efe..832473c 100644 --- a/src/frame.h +++ b/src/frame.h @@ -74,6 +74,35 @@ struct layout_parameters }; +enum wrap_box_type +{ + WRAP_BOX_PANGO, +}; + + +struct wrap_box +{ + enum wrap_box_type type; + int width; /* Pango units */ + + /* For type == WRAP_BOX_PANGO */ + PangoGlyphItem *glyph_item; + char *text; +}; + + +struct wrap_line +{ + int width; + int height; /* Pango units */ + int ascent; /* Pango units */ + + int n_boxes; + int max_boxes; + struct wrap_box *boxes; +}; + + struct frame { struct frame **children; @@ -81,9 +110,16 @@ struct frame int max_children; char *sc; /* Storycode */ + size_t sc_len; /* Space allocated for sc */ cairo_surface_t *contents; + int n_lines; + int max_lines; + struct wrap_line *lines; + + size_t pos; + struct layout_parameters lop; struct style *style; /* Non-NULL if 'lop' came from SS */ diff --git a/src/mainwindow.c b/src/mainwindow.c index 476d9e3..4eb3549 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -562,8 +562,10 @@ static gint add_furniture(GtkWidget *widget, struct presentation *p) fr = add_subframe(p->cur_edit_slide->top); fr->style = sty; set_edit(p, p->cur_edit_slide); - fr->sc = "Hello"; + fr->sc = strdup("Hello"); + fr->sc_len = 6; set_selection(p, fr); + fr->pos = 0; do_slide_update(p, p->pc); @@ -765,12 +767,11 @@ static void draw_editing_box(cairo_t *cr, struct frame *fr) } -static void draw_caret(cairo_t *cr, struct frame *fr) +static void draw_caret(cairo_t *cr, struct frame *fr, int pos) { #if 0 double xposd, yposd, cx; double clow, chigh; - PangoRectangle pos; const double t = 1.8; pango_layout_get_cursor_pos(o->layout, @@ -778,9 +779,9 @@ static void draw_caret(cairo_t *cr, struct frame *fr) &pos, NULL); xposd = pos.x/PANGO_SCALE; - cx = o->base.x - o->offs_x + xposd; + cx = fr->x + xposd; yposd = pos.y/PANGO_SCALE; - clow = o->base.y - o->offs_y + yposd; + clow = fr->y + yposd; chigh = clow + (pos.height/PANGO_SCALE); cairo_move_to(cr, cx, clow); @@ -813,7 +814,7 @@ static void draw_overlay(cairo_t *cr, struct presentation *p) /* If only one frame is selected, draw the caret */ if ( p->n_selection == 1 ) { - draw_caret(cr, p->selection[0]); + draw_caret(cr, p->selection[0], p->cursor_pos); } } @@ -884,6 +885,53 @@ static gint realise_sig(GtkWidget *da, struct presentation *p) } +static void insert_text(struct frame *fr, char *t, struct presentation *p) +{ + char *tmp; + size_t tlen, olen, offs; + int i; + + tlen = strlen(t); + olen = strlen(fr->sc); + + if ( tlen + olen + 1 > fr->sc_len ) { + + char *try; + + try = realloc(fr->sc, fr->sc_len + tlen + 64); + if ( try == NULL ) return; /* Failed to insert */ + fr->sc = try; + fr->sc_len += 64; + fr->sc_len += tlen; + + } + + tmp = malloc(fr->sc_len); + if ( tmp == NULL ) return; + + offs = fr->pos; + + for ( i=0; i<offs; i++ ) { + tmp[i] = fr->sc[i]; + } + for ( i=0; i<tlen; i++ ) { + tmp[i+offs] = t[i]; + } + for ( i=0; i<olen-fr->pos; i++ ) { + tmp[i+offs+tlen] = fr->sc[i+offs]; + } + tmp[olen+tlen] = '\0'; + memcpy(fr->sc, tmp, fr->sc_len); + free(tmp); + + rerender_slide(p, p->pc); + redraw_editor(p); + fr->pos += tlen; + fr->empty = 0; +} + + + static gboolean im_commit_sig(GtkIMContext *im, gchar *str, struct presentation *p) { @@ -896,7 +944,7 @@ static gboolean im_commit_sig(GtkIMContext *im, gchar *str, return FALSE; } - //im_commit(p->editing_object, str); FIXME! + insert_text(p->selection[0], str, p); return FALSE; } diff --git a/src/presentation.h b/src/presentation.h index c43cb9a..6a31fdd 100644 --- a/src/presentation.h +++ b/src/presentation.h @@ -76,6 +76,7 @@ struct presentation struct frame **selection; int n_selection; int max_selection; + size_t cursor_pos; /* This is the "native" size of the slide. It only exists to give * font size some meaning in the context of a somewhat arbitrary DPI */ diff --git a/src/render.c b/src/render.c index cd253c3..0650f96 100644 --- a/src/render.c +++ b/src/render.c @@ -40,35 +40,6 @@ #include "render.h" -enum wrap_box_type -{ - WRAP_BOX_PANGO, -}; - - -struct wrap_box -{ - enum wrap_box_type type; - int width; /* Pango units */ - - /* For type == WRAP_BOX_PANGO */ - PangoGlyphItem *glyph_item; - char *text; -}; - - -struct wrap_line -{ - int width; - int height; /* Pango units */ - int ascent; /* Pango units */ - - int n_boxes; - int max_boxes; - struct wrap_box *boxes; -}; - - struct renderstuff { cairo_t *cr; @@ -82,11 +53,7 @@ struct renderstuff int wrap_w; /* Pango units */ - /* Lines of boxes, where each box can be a load of glyphs, an image, - * etc */ - int n_lines; - int max_lines; - struct wrap_line *lines; + struct frame *fr; }; @@ -110,17 +77,17 @@ static void free_line_bits(struct wrap_line *l) } -static void alloc_lines(struct renderstuff *s) +static void alloc_lines(struct frame *fr) { struct wrap_line *lines_new; - lines_new = realloc(s->lines, s->max_lines * sizeof(struct wrap_line)); + lines_new = realloc(fr->lines, fr->max_lines * sizeof(struct wrap_line)); if ( lines_new == NULL ) { fprintf(stderr, "Couldn't allocate memory for lines!\n"); return; } - s->lines = lines_new; + fr->lines = lines_new; } @@ -190,7 +157,7 @@ static const char *add_chars_to_line(struct renderstuff *s, before = pango_glyph_item_split(orig, cur_text_ptr, split_len); - add_glyph_box_to_line(&s->lines[s->n_lines], + add_glyph_box_to_line(&s->fr->lines[s->fr->n_lines], before, before_text); orig->item->offset = 0; @@ -199,7 +166,8 @@ static const char *add_chars_to_line(struct renderstuff *s, PangoGlyphItem *copy; copy = pango_glyph_item_copy(orig); - add_glyph_box_to_line(&s->lines[s->n_lines], copy, before_text); + add_glyph_box_to_line(&s->fr->lines[s->fr->n_lines], + copy, before_text); } @@ -221,15 +189,15 @@ static void initialise_line(struct wrap_line *l) static void dispatch_line(struct renderstuff *s) { - s->n_lines++; + s->fr->n_lines++; - if ( s->n_lines == s->max_lines ) { - s->max_lines += 32; - alloc_lines(s); - if ( s->n_lines == s->max_lines ) return; + if ( s->fr->n_lines == s->fr->max_lines ) { + s->fr->max_lines += 32; + alloc_lines(s->fr); + if ( s->fr->n_lines == s->fr->max_lines ) return; } - initialise_line(&s->lines[s->n_lines]); + initialise_line(&s->fr->lines[s->fr->n_lines]); } @@ -272,7 +240,8 @@ static void wrap_text(gpointer data, gpointer user_data) gitem.item = item; /* FIXME: Replace this with a real typesetting algorithm */ - width_remain = s->wrap_w*PANGO_SCALE - s->lines[s->n_lines].width; + width_remain = s->wrap_w*PANGO_SCALE + - s->fr->lines[s->fr->n_lines].width; width_used = 0; pos = 0; n = item->num_chars; @@ -390,9 +359,9 @@ static void render_lines(struct renderstuff *s) int i; double y_pos = 0.0; - for ( i=0; i<s->n_lines; i++ ) { + for ( i=0; i<s->fr->n_lines; i++ ) { - double asc = s->lines[i].ascent/PANGO_SCALE; + double asc = s->fr->lines[i].ascent/PANGO_SCALE; //cairo_move_to(s->cr, 0, y_pos+asc+0.5); //cairo_line_to(s->cr, s->lines[i].width, y_pos+asc+0.5); @@ -404,10 +373,10 @@ static void render_lines(struct renderstuff *s) cairo_move_to(s->cr, 0.0, asc+y_pos); /* Render the line */ - render_boxes(&s->lines[i], s); + render_boxes(&s->fr->lines[i], s); /* FIXME: line spacing */ - y_pos += s->lines[i].height/PANGO_SCALE + 0.0; + y_pos += s->fr->lines[i].height/PANGO_SCALE + 0.0; } } @@ -424,6 +393,14 @@ static int render_sc(struct frame *fr) struct scblock *b; int i; + for ( i=0; i<fr->n_lines; i++ ) { + free_line_bits(&fr->lines[i]); + } + free(fr->lines); + fr->lines = NULL; + fr->n_lines = 0; + fr->max_lines = 0; + if ( fr->sc == NULL ) return 0; bl = sc_find_blocks(fr->sc, NULL); @@ -434,11 +411,12 @@ static int render_sc(struct frame *fr) } s.wrap_w = fr->w - fr->lop.pad_l - fr->lop.pad_r; - s.lines = NULL; - s.n_lines = 0; - s.max_lines = 64; - alloc_lines(&s); - initialise_line(&s.lines[0]); + s.fr = fr; + s.fr->lines = NULL; + s.fr->n_lines = 0; + s.fr->max_lines = 64; + alloc_lines(s.fr); + initialise_line(&s.fr->lines[0]); /* Find and load font */ s.fontmap = pango_cairo_font_map_get_default(); @@ -477,11 +455,6 @@ static int render_sc(struct frame *fr) cairo_translate(s.cr, fr->lop.pad_l, fr->lop.pad_t); render_lines(&s); - for ( i=0; i<s.n_lines; i++ ) { - free_line_bits(&s.lines[i]); - } - free(s.lines); - cairo_font_options_destroy(fopts); cairo_destroy(s.cr); pango_attr_list_unref(s.attrs); |