aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.me.uk>2019-10-10 20:33:59 +0200
committerThomas White <taw@bitwiz.me.uk>2019-10-10 20:33:59 +0200
commit0243f814940b6f2a02664b5a19ef21e636e2af2e (patch)
tree4a84fe8c149169e0f5d6808d9753c52b54916e32
parent1659e38235bd4fef10adede67ba070eb217f67b1 (diff)
Keep 'run' out of struct slide_pos
-rw-r--r--libstorycode/gtk/gtkslideview.c2
-rw-r--r--libstorycode/slide_render_cairo.c65
-rw-r--r--libstorycode/slide_render_cairo.h3
-rw-r--r--libstorycode/storycode.y14
4 files changed, 70 insertions, 14 deletions
diff --git a/libstorycode/gtk/gtkslideview.c b/libstorycode/gtk/gtkslideview.c
index 6c23cad..82f0a7f 100644
--- a/libstorycode/gtk/gtkslideview.c
+++ b/libstorycode/gtk/gtkslideview.c
@@ -192,7 +192,7 @@ static int gtksv_get_cursor_pos(SlideItem *item, Stylesheet *stylesheet,
slide_item_get_padding(item, stylesheet, &padl, &padr, &padt, &padb,
slide_w, slide_h);
- offs = slide_pos_trail_to_offset(item, cpos.para, cpos.run, cpos.pos, cpos.trail);
+ offs = slide_pos_trail_to_offset(item, cpos.para, cpos.pos, cpos.trail);
pango_layout_get_cursor_pos(item->paras[cpos.para].layout, offs, &rect, NULL);
*x = pango_units_to_double(rect.x) + padl;
*y = pango_units_to_double(rect.y) + gtksv_para_top(item, cpos.para) + padt;
diff --git a/libstorycode/slide_render_cairo.c b/libstorycode/slide_render_cairo.c
index e68e51e..bbfc0f9 100644
--- a/libstorycode/slide_render_cairo.c
+++ b/libstorycode/slide_render_cairo.c
@@ -65,17 +65,66 @@ static int slide_positions_equal(struct slide_pos a, struct slide_pos b)
}
-size_t slide_pos_trail_to_offset(SlideItem *item, int para, int run,
- size_t offs, int trail)
+static int slide_which_run(struct slide_text_paragraph *para, size_t item_offs,
+ size_t *run_offs)
+{
+ int run;
+ size_t pos = 0;
+
+ assert(para->n_runs > 0);
+
+ for ( run=0; run<para->n_runs; run++ ) {
+ size_t npos = pos + strlen(para->runs[run].text);
+ if ( npos >= item_offs ) break;
+ pos = npos;
+ }
+ if ( run_offs != NULL ) {
+ *run_offs = item_offs - pos;
+ }
+ return run;
+}
+
+
+static int slide_item_is_text(SlideItem *item)
+{
+ switch ( item->type ) {
+
+ case SLIDE_ITEM_TEXT : return 1;
+ case SLIDE_ITEM_IMAGE : return 0;
+ case SLIDE_ITEM_FOOTER : return 0;
+ case SLIDE_ITEM_SLIDETITLE : return 1;
+ case SLIDE_ITEM_PRESTITLE : return 1;
+
+ default :
+ fprintf(stderr, "Please update slide_item_is_text\n");
+ return 0;
+ }
+}
+
+
+size_t slide_pos_trail_to_offset(SlideItem *item, int para_num, size_t offs, int trail)
{
glong char_offs;
char *ptr;
+ int run;
+ size_t run_offs;
+ size_t prev_len;
+ int j;
+ struct slide_text_paragraph *para;
+
+ if ( !slide_item_is_text(item) ) return offs;
- char_offs = g_utf8_pointer_to_offset(item->paras[para].runs[run].text,
- item->paras[para].runs[run].text+offs);
+ para = &item->paras[para_num];
+ run = slide_which_run(para, offs, &run_offs);
+
+ char_offs = g_utf8_pointer_to_offset(para->runs[run].text,
+ para->runs[run].text+run_offs);
char_offs += trail;
- ptr = g_utf8_offset_to_pointer(item->paras[para].runs[run].text, char_offs);
- return ptr - item->paras[para].runs[run].text;
+ ptr = g_utf8_offset_to_pointer(para->runs[run].text, char_offs);
+
+ prev_len = 0;
+ for ( j=0; j<run; j++ ) prev_len += strlen(para->runs[j].text);
+ return prev_len + ptr - para->runs[run].text;
}
@@ -181,9 +230,9 @@ static void render_text(SlideItem *item, cairo_t *cr, PangoContext *pc,
}
if ( !slide_positions_equal(sel_start, sel_end) ) {
- sel_s = slide_pos_trail_to_offset(item, sel_start.para, sel_start.run,
+ sel_s = slide_pos_trail_to_offset(item, sel_start.para,
sel_start.pos, sel_start.trail);
- sel_e = slide_pos_trail_to_offset(item, sel_end.para, sel_end.run,
+ sel_e = slide_pos_trail_to_offset(item, sel_end.para,
sel_end.pos, sel_end.trail);
} else {
sel_s = 0;
diff --git a/libstorycode/slide_render_cairo.h b/libstorycode/slide_render_cairo.h
index f90a27c..808b661 100644
--- a/libstorycode/slide_render_cairo.h
+++ b/libstorycode/slide_render_cairo.h
@@ -33,7 +33,6 @@
struct slide_pos
{
int para; /* Paragraph number (corresponding to narrative items) */
- int run; /* Run number */
int pos; /* Byte position within run (yes, really) */
int trail; /* 1 = end of character, 0 = before */
};
@@ -45,6 +44,6 @@ extern int slide_render_cairo(Slide *s, cairo_t *cr, ImageStore *is, Stylesheet
extern int render_slides_to_pdf(Narrative *n, ImageStore *is, const char *filename);
-extern size_t slide_pos_trail_to_offset(SlideItem *item, int para_num, int run, size_t offs, int trail);
+extern size_t slide_pos_trail_to_offset(SlideItem *item, int para_num, size_t offs, int trail);
#endif /* RENDER_H */
diff --git a/libstorycode/storycode.y b/libstorycode/storycode.y
index 587db4a..f3c2653 100644
--- a/libstorycode/storycode.y
+++ b/libstorycode/storycode.y
@@ -268,10 +268,18 @@ struct text_run **combine_paras(struct parse_many_paragraphs mp, int **pn_runs)
combined_paras = malloc(mp.n_paras * sizeof(struct text_run *));
n_runs = malloc(mp.n_paras * sizeof(int));
for ( i=0; i<mp.n_paras; i++ ) {
- for ( int j=0; j<mp.paras[i].n_runs; j++ ) {
+ if ( mp.paras[i].n_runs > 0 ) {
+ combined_paras[i] = mp.paras[i].runs;
+ n_runs[i] = mp.paras[i].n_runs;
+ } else {
+ /* Create a single dummy run */
+ struct text_run *run;
+ run = malloc(sizeof(struct text_run));
+ run->text = strdup("");
+ run->type = TEXT_RUN_NORMAL;
+ combined_paras[i] = run;
+ n_runs[i] = 1;
}
- combined_paras[i] = mp.paras[i].runs;
- n_runs[i] = mp.paras[i].n_runs;
}
*pn_runs = n_runs;