diff options
author | Thomas White <taw@bitwiz.org.uk> | 2011-09-25 19:29:11 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2011-09-25 19:29:11 +0200 |
commit | 1dbcef5a7428a7132b746653af671b3a15fc7951 (patch) | |
tree | 4b902092d0c011739017f26989779d2538c37d57 /src/tool_text.c | |
parent | e26dcd2049ae065f5a821f087abd736ba553dcad (diff) |
First part of new concept for styles and layout elements
Diffstat (limited to 'src/tool_text.c')
-rw-r--r-- | src/tool_text.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/src/tool_text.c b/src/tool_text.c new file mode 100644 index 0000000..9419a12 --- /dev/null +++ b/src/tool_text.c @@ -0,0 +1,203 @@ +/* + * tool_text.c + * + * Colloquium - A tiny presentation program + * + * Copyright (c) 2011 Thomas White <taw@bitwiz.org.uk> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "presentation.h" +#include "objects.h" +#include "mainwindow.h" + + +struct object *add_text_object(struct slide *s, double x, double y, + struct style *sty) +{ + struct object *new; + + new = new_object(TEXT, sty); + + new->x = x; new->y = y; + new->bb_width = 10.0; + new->bb_height = 40.0; + new->text = malloc(1); + new->text[0] = '\0'; + new->text_len = 1; + new->insertion_point = 0; + new->layout = NULL; + new->fontdesc = NULL; + + if ( add_object_to_slide(s, new) ) { + free_object(new); + return NULL; + } + s->object_seq++; + + return new; +} + + +void insert_text(struct object *o, char *t) +{ + char *tmp; + size_t tlen, olen; + int i; + + assert(o->type == TEXT); + tlen = strlen(t); + olen = strlen(o->text); + + if ( tlen + olen + 1 > o->text_len ) { + + char *try; + + try = realloc(o->text, o->text_len + tlen + 64); + if ( try == NULL ) return; /* Failed to insert */ + o->text = try; + o->text_len += 64; + o->text_len += tlen; + + } + + tmp = malloc(o->text_len); + if ( tmp == NULL ) return; + + for ( i=0; i<o->insertion_point; i++ ) { + tmp[i] = o->text[i]; + } + for ( i=0; i<tlen; i++ ) { + tmp[i+o->insertion_point] = t[i]; + } + for ( i=0; i<olen-o->insertion_point; i++ ) { + tmp[i+o->insertion_point+tlen] = o->text[i+o->insertion_point]; + } + tmp[olen+tlen] = '\0'; + memcpy(o->text, tmp, o->text_len); + free(tmp); + + o->insertion_point += tlen; + o->parent->object_seq++; + o->empty = 0; +} + + +void set_text_style(struct object *o, struct style *sty) +{ + assert(o->type == TEXT); + o->style = sty; + o->parent->object_seq++; +} + + +static int find_prev_index(const char *t, int p) +{ + int i, nback; + + if ( p == 0 ) return 0; + + if ( !(t[p-1] & 0x80) ) { + nback = 1; + } else { + nback = 0; + for ( i=1; i<=6; i++ ) { + if ( p-i == 0 ) return 0; + if ( !(t[p-i] & 0xC0) ) nback++; + } + } + + return p - nback; +} + + +static int find_next_index(const char *t, int p) +{ + int i, nfor; + + if ( t[p] == '\0' ) return p; + + if ( !(t[p+1] & 0x80) ) { + nfor = 1; + } else { + nfor = 0; + for ( i=1; i<=6; i++ ) { + if ( t[p+i] == '\0' ) return p+i; + if ( !(t[p+i] & 0xC0) ) nfor++; + } + } + + return p + nfor; +} + + +void handle_text_backspace(struct object *o) +{ + int prev_index; + + assert(o->type == TEXT); + + if ( o->insertion_point == 0 ) return; /* Nothing to delete */ + + prev_index = find_prev_index(o->text, o->insertion_point); + + memmove(o->text+prev_index, o->text+o->insertion_point, + o->text_len-o->insertion_point); + + o->insertion_point = prev_index; + + if ( strlen(o->text) == 0 ) o->empty = 1; + + o->parent->object_seq++; +} + + +void move_cursor_left(struct object *o) +{ + o->insertion_point = find_prev_index(o->text, o->insertion_point); +} + + +void move_cursor_right(struct object *o) +{ + o->insertion_point = find_next_index(o->text, o->insertion_point); +} + + +void position_caret(struct object *o, double x, double y) +{ + int idx, trail; + int xp, yp; + gboolean v; + + assert(o->type == TEXT); + + xp = (x - o->x)*PANGO_SCALE; + yp = (y - o->y)*PANGO_SCALE; + + v = pango_layout_xy_to_index(o->layout, xp, yp, &idx, &trail); + + o->insertion_point = idx+trail; +} |