aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2013-03-18 23:52:13 +0100
committerThomas White <taw@bitwiz.org.uk>2013-03-19 08:17:08 +0100
commit561261eff94ab93131c23859fb850e6dc36f87ab (patch)
tree157f74976ac04b5e8ac89508b233b98fdc51d14f /src
parentef2b60cfeeeb8a03a4122d0a244b01c26e33968b (diff)
Cursor position stuff
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.c5
-rw-r--r--src/storycode.c15
-rw-r--r--src/storycode.h2
-rw-r--r--src/wrap.c55
-rw-r--r--src/wrap.h2
5 files changed, 54 insertions, 25 deletions
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 05f5a3d..562a95b 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -37,6 +37,7 @@
#include "render.h"
#include "frame.h"
#include "slideshow.h"
+#include "wrap.h"
/* Update a slide, once it's been edited in some way. */
@@ -566,6 +567,7 @@ static gint add_furniture(GtkWidget *widget, struct presentation *p)
fr->sc_len = 6;
set_selection(p, fr);
fr->pos = 0;
+ p->cursor_pos = 0;
do_slide_update(p, p->pc);
@@ -919,8 +921,9 @@ static void insert_text(struct frame *fr, char *t, struct presentation *p)
free(tmp);
rerender_slide(p, p->pc);
- redraw_editor(p);
fr->pos += tlen;
+ p->cursor_pos = fr->pos;
+ redraw_editor(p);
fr->empty = 0;
}
diff --git a/src/storycode.c b/src/storycode.c
index 45638b4..53dc650 100644
--- a/src/storycode.c
+++ b/src/storycode.c
@@ -123,7 +123,7 @@ struct scblock *sc_block_list_next(SCBlockList *bl, SCBlockListIterator *iter)
}
-static int sc_block_list_add(SCBlockList *bl,
+static int sc_block_list_add(SCBlockList *bl, size_t offset,
char *name, char *options, char *contents)
{
if ( bl->n_blocks == bl->max_blocks ) {
@@ -134,6 +134,7 @@ static int sc_block_list_add(SCBlockList *bl,
bl->blocks[bl->n_blocks].name = name;
bl->blocks[bl->n_blocks].options = options;
bl->blocks[bl->n_blocks].contents = contents;
+ bl->blocks[bl->n_blocks].offset = offset;
bl->n_blocks++;
return 0;
@@ -254,7 +255,7 @@ SCBlockList *sc_find_blocks(const char *sc, const char *blockname)
{
SCBlockList *bl;
char *tbuf;
- size_t len, i, j;
+ size_t len, i, j, start;
bl = sc_block_list_new();
if ( bl == NULL ) return NULL;
@@ -278,7 +279,7 @@ SCBlockList *sc_find_blocks(const char *sc, const char *blockname)
if ( (blockname == NULL) && (j != 0) ) {
tbuf[j] = '\0';
- if ( sc_block_list_add(bl, NULL, NULL,
+ if ( sc_block_list_add(bl, i, NULL, NULL,
strdup(tbuf)) )
{
fprintf(stderr,
@@ -302,7 +303,7 @@ SCBlockList *sc_find_blocks(const char *sc, const char *blockname)
if ( (blockname == NULL)
|| ((blockname != NULL) && !strcmp(blockname, name)) )
{
- if ( sc_block_list_add(bl, name, options,
+ if ( sc_block_list_add(bl, i, name, options,
contents) )
{
fprintf(stderr,
@@ -313,6 +314,10 @@ SCBlockList *sc_find_blocks(const char *sc, const char *blockname)
}
}
+ /* Start of the next block */
+ start = i;
+
+
} else {
tbuf[j++] = sc[i++];
@@ -322,7 +327,7 @@ SCBlockList *sc_find_blocks(const char *sc, const char *blockname)
if ( (blockname == NULL) && (j != 0) ) {
tbuf[j] = '\0';
- if ( sc_block_list_add(bl, NULL, NULL, tbuf) )
+ if ( sc_block_list_add(bl, start, NULL, NULL, tbuf) )
{
fprintf(stderr,
"Failed to add block.\n");
diff --git a/src/storycode.h b/src/storycode.h
index 39ff18b..fbdd53f 100644
--- a/src/storycode.h
+++ b/src/storycode.h
@@ -33,6 +33,8 @@ struct scblock
char *name;
char *options;
char *contents;
+
+ size_t offset;
};
struct scblock *sc_block_list_first(SCBlockList *bl,
diff --git a/src/wrap.c b/src/wrap.c
index e040d25..ca841f5 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -83,28 +83,43 @@ static void initialise_line(struct wrap_line *l)
void get_cursor_pos(struct frame *fr, size_t pos,
double *xposd, double *yposd, double *line_height)
{
- signed int line;
+ int line, box;
int i;
+ struct wrap_line *l;
+ struct wrap_box *b;
+ int p;
*xposd = 0;
*yposd = 0;
line = 0;
- for ( i=0; i<fr->n_lines; i++ ) {
+ for ( i=0; i<fr->n_lines-1; i++ ) {
line = i;
- if ( fr->lines[i].sc_offset > pos ) {
- line = i-1;
- break;
- }
+ if ( fr->lines[i+1].sc_offset > pos ) break;
*yposd += fr->lines[i].height;
- *line_height = pango_units_to_double(fr->lines[i].height);
}
assert(line >= 0);
- *xposd += fr->lop.pad_l;
-
+ *line_height = pango_units_to_double(fr->lines[line].height);
*yposd /= PANGO_SCALE;
*yposd += fr->lop.pad_t;
+
+ l = &fr->lines[line];
+ box = 0;
+ for ( i=0; i<l->n_boxes-1; i++ ) {
+ box = i;
+ if ( l->boxes[i+1].sc_offset > pos ) break;
+ *xposd += l->boxes[i].width;
+ *xposd += l->boxes[i].sp;
+ }
+
+ b = &l->boxes[box];
+ pango_glyph_string_index_to_x(b->glyphs, b->text, strlen(b->text),
+ &b->item->analysis, pos - b->sc_offset,
+ FALSE, &p);
+ *xposd += p;
+ *xposd /= PANGO_SCALE;
+ *xposd += fr->lop.pad_l;
}
@@ -116,6 +131,7 @@ static void shape_and_measure(gpointer data, gpointer user_data)
/* FIXME: Don't assume only one run per wrap box */
box->glyphs = pango_glyph_string_new();
+ box->item = item;
pango_shape(box->text+item->offset, item->length, &item->analysis,
box->glyphs);
@@ -129,8 +145,6 @@ static void shape_and_measure(gpointer data, gpointer user_data)
if ( PANGO_ASCENT(rect) > box->ascent ) {
box->ascent = PANGO_ASCENT(rect);
}
-
- pango_item_free(item);
}
@@ -151,7 +165,7 @@ static void calc_line_geometry(struct wrap_line *line)
/* Add "text", followed by a space of type "space", to "line" */
-static int add_wrap_box(struct wrap_line *line, char *text,
+static int add_wrap_box(struct wrap_line *line, char *text, size_t offset,
enum wrap_box_space space, PangoContext *pc,
PangoFont *font, PangoFontDescription *fontdesc,
double col[4])
@@ -168,6 +182,7 @@ static int add_wrap_box(struct wrap_line *line, char *text,
}
box = &line->boxes[line->n_boxes];
+ box->sc_offset = offset;
box->type = WRAP_BOX_PANGO;
box->text = text;
box->space = space;
@@ -194,7 +209,7 @@ static int add_wrap_box(struct wrap_line *line, char *text,
static int split_words(struct wrap_line *boxes, PangoContext *pc, char *sc,
- PangoLanguage *lang,
+ size_t sc_offset, PangoLanguage *lang,
PangoFont *font, PangoFontDescription *fontdesc,
double col[4])
{
@@ -245,8 +260,8 @@ static int split_words(struct wrap_line *boxes, PangoContext *pc, char *sc,
return 1;
}
- if ( add_wrap_box(boxes, word, type, pc, font, fontdesc,
- col) ) {
+ if ( add_wrap_box(boxes, word, start, type, pc,
+ font, fontdesc, col) ) {
fprintf(stderr, "Failed to add wrap box.\n");
}
start = i;
@@ -264,8 +279,8 @@ static int split_words(struct wrap_line *boxes, PangoContext *pc, char *sc,
return 1;
}
- add_wrap_box(boxes, word, WRAP_SPACE_NONE, pc, font, fontdesc,
- col);
+ add_wrap_box(boxes, word, start, WRAP_SPACE_NONE, pc,
+ font, fontdesc, col);
}
@@ -322,8 +337,8 @@ static struct wrap_line *sc_to_wrap_boxes(const char *sc, PangoContext *pc)
b = sc_block_list_next(bl, iter) )
{
if ( b->name == NULL ) {
- if ( split_words(boxes, pc, b->contents, lang,
- font, fontdesc, col) ) {
+ if ( split_words(boxes, pc, b->contents, b->offset,
+ lang, font, fontdesc, col) ) {
fprintf(stderr, "Splitting failed.\n");
}
}
@@ -507,6 +522,7 @@ static void output_line(int q, int s, struct frame *fr, struct wrap_line *boxes)
l->max_boxes = s-q;
alloc_boxes(l);
+ l->sc_offset = boxes->boxes[q].sc_offset;
for ( j=q; j<s; j++ ) {
l->boxes[l->n_boxes++] = boxes->boxes[j];
}
@@ -739,6 +755,7 @@ void wrap_line_free(struct wrap_line *l)
case WRAP_BOX_PANGO :
pango_glyph_string_free(l->boxes[i].glyphs);
+ pango_item_free(l->boxes[i].item);
free(l->boxes[i].text);
break;
diff --git a/src/wrap.h b/src/wrap.h
index 2dd81ce..2bdc8dc 100644
--- a/src/wrap.h
+++ b/src/wrap.h
@@ -57,6 +57,7 @@ enum wrap_box_space
struct wrap_box
{
enum wrap_box_type type;
+ size_t sc_offset; /* How far into the SC for this frame */
/* Pango units */
int width;
@@ -68,6 +69,7 @@ struct wrap_box
/* For type == WRAP_BOX_PANGO */
PangoGlyphString *glyphs;
+ PangoItem *item;
PangoFont *font;
char *text;
double col[4]; /* rgba colour */