Take paraspace into account in cursor calculations
authorThomas White <taw@bitwiz.me.uk>
Thu, 10 Oct 2019 19:52:21 +0000 (21:52 +0200)
committerThomas White <taw@bitwiz.me.uk>
Thu, 10 Oct 2019 19:52:21 +0000 (21:52 +0200)
libstorycode/gtk/gtkslideview.c
libstorycode/narrative_render_cairo.c
libstorycode/slide.c
libstorycode/slide_render_cairo.c
libstorycode/stylesheet.c
libstorycode/stylesheet.h

index 82f0a7f..42165ac 100644 (file)
@@ -161,7 +161,7 @@ static void draw_resize_handle(cairo_t *cr, double x, double y)
 }
 
 
-static double gtksv_para_top(SlideItem *item, int pnum)
+static double gtksv_para_top(SlideItem *item, int pnum, double paraspace_t, double paraspace_b)
 {
        int i;
        double py = 0.0;
@@ -169,8 +169,37 @@ static double gtksv_para_top(SlideItem *item, int pnum)
                PangoRectangle rect;
                pango_layout_get_extents(item->paras[i].layout, NULL, &rect);
                py += pango_units_to_double(rect.height);
+               py += paraspace_t;
+               py += paraspace_b;
+       }
+       return py + paraspace_t;
+}
+
+
+static void get_paraspace(SlideItem *item, Stylesheet *stylesheet,
+                          double paraspace[4], double slide_w, double slide_h)
+{
+       struct length paraspacel[4];
+       const char *stn;
+
+       switch ( item->type ) {
+               case SLIDE_ITEM_TEXT : stn = "SLIDE.TEXT"; break;
+               case SLIDE_ITEM_SLIDETITLE : stn = "SLIDE.SLIDETITLE"; break;
+               case SLIDE_ITEM_PRESTITLE : stn = "SLIDE.PRESTITLE"; break;
+               default : stn = NULL; break;
+       }
+
+       if ( stylesheet_get_paraspace(stylesheet, stn, paraspacel) == 0 ) {
+               paraspace[0] = lcalc(paraspacel[0], slide_w);
+               paraspace[1] = lcalc(paraspacel[1], slide_w);
+               paraspace[2] = lcalc(paraspacel[2], slide_h);
+               paraspace[3] = lcalc(paraspacel[3], slide_h);
+       } else {
+               paraspace[0] = 0.0;
+               paraspace[1] = 0.0;
+               paraspace[2] = 0.0;
+               paraspace[3] = 0.0;
        }
-       return py;
 }
 
 
@@ -181,6 +210,7 @@ static int gtksv_get_cursor_pos(SlideItem *item, Stylesheet *stylesheet,
        size_t offs;
        PangoRectangle rect;
        double padl, padr, padt, padb;
+       double paraspace[4];
 
        if ( item->paras == NULL ) return 1;
 
@@ -191,11 +221,14 @@ static int gtksv_get_cursor_pos(SlideItem *item, Stylesheet *stylesheet,
 
        slide_item_get_padding(item, stylesheet, &padl, &padr, &padt, &padb,
                               slide_w, slide_h);
+       get_paraspace(item, stylesheet, paraspace, slide_w, slide_h);
 
        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;
+       *x = pango_units_to_double(rect.x) + padl + paraspace[0];
+       *y = pango_units_to_double(rect.y)
+            + gtksv_para_top(item, cpos.para, paraspace[2], paraspace[3])
+            + padt;
        *h = pango_units_to_double(rect.height);
        return 0;
 }
@@ -525,6 +558,7 @@ static int gtksv_find_cursor(SlideItem *item, Stylesheet *stylesheet,
        double top;
        int i = 0;
        double padl, padr, padt, padb;
+       double paraspace[4];
 
        if ( !is_text(item->type) ) {
                pos->para = 0;
@@ -535,7 +569,9 @@ static int gtksv_find_cursor(SlideItem *item, Stylesheet *stylesheet,
 
        slide_item_get_padding(item, stylesheet, &padl, &padr, &padt, &padb,
                               slide_w, slide_h);
+       get_paraspace(item, stylesheet, paraspace, slide_w, slide_h);
        x -= padl;
+       x -= paraspace[0];
        y -= padt;
 
        if ( item->paras == NULL ) {
@@ -551,6 +587,8 @@ static int gtksv_find_cursor(SlideItem *item, Stylesheet *stylesheet,
                pango_layout_get_extents(item->paras[i++].layout, NULL, &rect);
                top = cur_y;
                cur_y += pango_units_to_double(rect.height);
+               cur_y += paraspace[2];
+               cur_y += paraspace[3];
        } while ( (cur_y < y) && (i<item->n_paras) );
 
        pos->para = i-1;
index 63f0865..ebd14f9 100644 (file)
 const double dummy_h_val = 1024.0;
 
 
-static double narrative_lcalc(struct length l, double pd)
-{
-       if ( l.unit == LENGTH_UNIT ) {
-               return l.len;
-       } else {
-               return l.len * pd;
-       }
-}
-
-
 static void wrap_text(struct narrative_item *item, PangoContext *pc,
                       Stylesheet *ss, const char *stn, double w,
                       size_t sel_start, size_t sel_end)
@@ -259,10 +249,10 @@ int narrative_wrap_range(Narrative *n, Stylesheet *stylesheet, PangoLanguage *la
        struct length paraspace[4];
 
        if ( stylesheet_get_padding(stylesheet, "NARRATIVE", pad) ) return 1;
-       n->space_l = narrative_lcalc(pad[0], w);
-       n->space_r = narrative_lcalc(pad[1], w);
-       n->space_t = narrative_lcalc(pad[2], dummy_h_val);
-       n->space_b = narrative_lcalc(pad[3], dummy_h_val);
+       n->space_l = lcalc(pad[0], w);
+       n->space_r = lcalc(pad[1], w);
+       n->space_t = lcalc(pad[2], dummy_h_val);
+       n->space_b = lcalc(pad[3], dummy_h_val);
 
        n->w = w;
        w -= n->space_l + n->space_r;
@@ -334,10 +324,10 @@ int narrative_wrap_range(Narrative *n, Stylesheet *stylesheet, PangoLanguage *la
                }
 
                if ( stylesheet_get_paraspace(stylesheet, stn, paraspace) == 0 ) {
-                       n->items[i].space_l = narrative_lcalc(paraspace[0], w);
-                       n->items[i].space_r = narrative_lcalc(paraspace[1], w);
-                       n->items[i].space_t = narrative_lcalc(paraspace[2], dummy_h_val);
-                       n->items[i].space_b = narrative_lcalc(paraspace[3], dummy_h_val);
+                       n->items[i].space_l = lcalc(paraspace[0], w);
+                       n->items[i].space_r = lcalc(paraspace[1], w);
+                       n->items[i].space_t = lcalc(paraspace[2], dummy_h_val);
+                       n->items[i].space_b = lcalc(paraspace[3], dummy_h_val);
                }
 
                switch ( n->items[i].type ) {
index 09c91ba..07b01ff 100644 (file)
@@ -278,16 +278,6 @@ static const char *style_name_for_slideitem(enum slide_item_type t)
 }
 
 
-static double lcalc(struct length l, double pd)
-{
-       if ( l.unit == LENGTH_UNIT ) {
-               return l.len;
-       } else {
-               return l.len * pd;
-       }
-}
-
-
 void slide_item_get_geom(SlideItem *item, Stylesheet *ss,
                          double *x, double *y, double *w, double *h,
                          double slide_w, double slide_h)
index bbfc0f9..32bd236 100644 (file)
 #include "slide_priv.h"
 
 
-static double slide_lcalc(struct length l, double pd)
-{
-       if ( l.unit == LENGTH_UNIT ) {
-               return l.len;
-       } else {
-               return l.len * pd;
-       }
-}
-
-
 static int slide_positions_equal(struct slide_pos a, struct slide_pos b)
 {
        if ( a.para != b.para ) return 0;
@@ -206,15 +196,15 @@ static void render_text(SlideItem *item, cairo_t *cr, PangoContext *pc,
        } else {
                stylesheet_get_geometry(ss, stn, &geom);
        }
-       x = slide_lcalc(geom.x, parent_w);
-       y = slide_lcalc(geom.y, parent_h);
-       w = slide_lcalc(geom.w, parent_w);
-       h = slide_lcalc(geom.h, parent_h);
+       x = lcalc(geom.x, parent_w);
+       y = lcalc(geom.y, parent_h);
+       w = lcalc(geom.w, parent_w);
+       h = lcalc(geom.h, parent_h);
 
        if ( stylesheet_get_padding(ss, stn, pad) ) return;
-       pad_l = slide_lcalc(pad[0], parent_w);
-       pad_r = slide_lcalc(pad[1], parent_w);
-       pad_t = slide_lcalc(pad[2], parent_h);
+       pad_l = lcalc(pad[0], parent_w);
+       pad_r = lcalc(pad[1], parent_w);
+       pad_t = lcalc(pad[2], parent_h);
 
        font = stylesheet_get_font(ss, stn, &fgcol, &align);
        if ( font == NULL ) return;
@@ -242,10 +232,10 @@ static void render_text(SlideItem *item, cairo_t *cr, PangoContext *pc,
        do_background(ss, stn, cr, x, y, w, h);
 
        if ( stylesheet_get_paraspace(ss, stn, paraspacel) == 0 ) {
-               paraspace[0] = slide_lcalc(paraspacel[0], w);
-               paraspace[1] = slide_lcalc(paraspacel[1], w);
-               paraspace[2] = slide_lcalc(paraspacel[2], h);
-               paraspace[3] = slide_lcalc(paraspacel[3], h);
+               paraspace[0] = lcalc(paraspacel[0], w);
+               paraspace[1] = lcalc(paraspacel[1], w);
+               paraspace[2] = lcalc(paraspacel[2], h);
+               paraspace[3] = lcalc(paraspacel[3], h);
        } else {
                paraspace[0] = 0.0;
                paraspace[1] = 0.0;
@@ -331,10 +321,10 @@ static void render_image(SlideItem *item, cairo_t *cr,
        double wd, hd;
        cairo_surface_t *surf;
 
-       x = slide_lcalc(item->geom.x, parent_w);
-       y = slide_lcalc(item->geom.y, parent_h);
-       w = slide_lcalc(item->geom.w, parent_w);
-       h = slide_lcalc(item->geom.h, parent_h);
+       x = lcalc(item->geom.x, parent_w);
+       y = lcalc(item->geom.y, parent_h);
+       w = lcalc(item->geom.w, parent_w);
+       h = lcalc(item->geom.h, parent_h);
 
        wd = w;  hd = h;
        cairo_user_to_device_distance(cr, &wd, &hd);
index d649d48..8fa904e 100644 (file)
@@ -588,3 +588,13 @@ int stylesheet_set_from_storycode(Stylesheet *ss, const char *sc)
 
        return 0;
 }
+
+
+double lcalc(struct length l, double pd)
+{
+       if ( l.unit == LENGTH_UNIT ) {
+               return l.len;
+       } else {
+               return l.len * pd;
+       }
+}
index e5b4d62..82f90e8 100644 (file)
@@ -112,5 +112,6 @@ extern char *stylesheet_serialise(Stylesheet *s);
 extern const char *stylesheet_get_friendly_name(const char *in);
 
 extern void copy_col(struct colour *to, struct colour from);
+extern double lcalc(struct length l, double pd);
 
 #endif /* STYLESHEET_H */