From 0243f814940b6f2a02664b5a19ef21e636e2af2e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 10 Oct 2019 20:33:59 +0200 Subject: Keep 'run' out of struct slide_pos --- libstorycode/gtk/gtkslideview.c | 2 +- libstorycode/slide_render_cairo.c | 65 ++++++++++++++++++++++++++++++++++----- libstorycode/slide_render_cairo.h | 3 +- libstorycode/storycode.y | 14 +++++++-- 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; runn_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; jruns[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 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; -- cgit v1.2.3