diff options
author | Thomas White <taw@bitwiz.org.uk> | 2016-05-02 00:01:18 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2016-05-02 00:01:18 +0200 |
commit | d66afeb74fed4be680cc56ca5c0fb7fd0c1fa53c (patch) | |
tree | c5c75e8d335aaf422e034bf20e5bb42efa53ea13 /src | |
parent | 75967f41675ca5f4c9112460b67a2e77733eb1e4 (diff) |
Paragraph spacing
Diffstat (limited to 'src')
-rw-r--r-- | src/frame.c | 38 | ||||
-rw-r--r-- | src/frame.h | 3 | ||||
-rw-r--r-- | src/narrative_window.c | 4 | ||||
-rw-r--r-- | src/render.c | 5 | ||||
-rw-r--r-- | src/sc_interp.c | 60 |
5 files changed, 95 insertions, 15 deletions
diff --git a/src/frame.c b/src/frame.c index fbfd1f2..d2e9009 100644 --- a/src/frame.c +++ b/src/frame.c @@ -56,6 +56,7 @@ struct _paragraph { enum para_type type; double height; + float space[4]; /* For PARA_TYPE_TEXT */ int n_runs; @@ -283,6 +284,8 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w) PangoRectangle rect; size_t pos = 0; + w -= para->space[0] + para->space[1]; + if ( para->type != PARA_TYPE_TEXT ) return; for ( i=0; i<para->n_runs; i++ ) { @@ -340,6 +343,7 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w) pango_layout_get_extents(para->layout, NULL, &rect); para->height = pango_units_to_double(rect.height); + para->height += para->space[2] + para->space[3]; } @@ -544,6 +548,8 @@ void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is, { cairo_surface_t *surf; + cairo_translate(cr, para->space[0], para->space[2]); + switch ( para->type ) { case PARA_TYPE_TEXT : @@ -606,8 +612,10 @@ int find_cursor(struct frame *fr, double x, double y, if ( npos > y ) { *ppara = i; if ( fr->paras[i]->type == PARA_TYPE_TEXT ) { - *ppos = text_para_pos(fr->paras[i], x-fr->pad_l, - y-pos, ptrail); + *ppos = text_para_pos(fr->paras[i], + x - fr->pad_l - fr->paras[i]->space[0], + y - pos - fr->paras[i]->space[2], + ptrail); } else { *ppos = 0; } @@ -689,8 +697,8 @@ int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos, pango_layout_get_cursor_pos(para->layout, cursor_pos, &rect, NULL); - *cx = pango_units_to_double(rect.x) + fr->pad_l; - *cy = pango_units_to_double(rect.y) + fr->pad_t + py; + *cx = pango_units_to_double(rect.x) + fr->pad_l + para->space[0]; + *cy = pango_units_to_double(rect.y) + fr->pad_t + py + para->space[2]; *ch = pango_units_to_double(rect.height); return 0; } @@ -980,3 +988,25 @@ int get_sc_pos(struct frame *fr, int pn, size_t pos, return 0; } + + +void set_para_spacing(Paragraph *para, float space[4]) +{ + if ( para == NULL ) return; + para->space[0] = space[0]; + para->space[1] = space[1]; + para->space[2] = space[2]; + para->space[3] = space[3]; +} + + +Paragraph *current_para(struct frame *fr) +{ + if ( fr == NULL ) return NULL; + + if ( (fr->paras != NULL) && (fr->paras[fr->n_paras-1]->open) ) { + return fr->paras[fr->n_paras-1]; + } + + return NULL; +} diff --git a/src/frame.h b/src/frame.h index 907a910..e128d09 100644 --- a/src/frame.h +++ b/src/frame.h @@ -105,8 +105,11 @@ extern struct frame *find_frame_with_scblocks(struct frame *top, extern double total_height(struct frame *fr); extern Paragraph *last_open_para(struct frame *fr); +extern Paragraph *current_para(struct frame *fr); extern void close_last_paragraph(struct frame *fr); +extern void set_para_spacing(Paragraph *para, float space[4]); + extern double paragraph_height(Paragraph *para); extern void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is, enum is_size isz); diff --git a/src/narrative_window.c b/src/narrative_window.c index 6d4d21a..3be8a1d 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -405,7 +405,9 @@ static void nw_update_titlebar(NarrativeWindow *nw) static SCBlock *narrative_stylesheet() { - return sc_parse("\\stylesheet{\\ss[slide]{\\callback[sthumb]}}"); + return sc_parse("\\stylesheet{" + "\\ss[slide]{\\callback[sthumb]}" + "}"); } diff --git a/src/render.c b/src/render.c index e68fe5a..8699ed8 100644 --- a/src/render.c +++ b/src/render.c @@ -146,9 +146,12 @@ int recursive_draw(struct frame *fr, cairo_t *cr, void wrap_frame(struct frame *fr, PangoContext *pc) { int i; + double w; + + w = fr->w - fr->pad_l - fr->pad_r; for ( i=0; i<fr->n_paras; i++ ) { - wrap_paragraph(fr->paras[i], pc, fr->w - fr->pad_l - fr->pad_r); + wrap_paragraph(fr->paras[i], pc, w); } } diff --git a/src/sc_interp.c b/src/sc_interp.c index 9c4045b..9d89767 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -51,6 +51,7 @@ struct sc_state double col[4]; int ascent; int height; + float paraspace[4]; struct frame *fr; /* The current frame */ @@ -568,6 +569,10 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, st->macro_contents = NULL; st->macro_real_block = NULL; st->fr = NULL; + st->paraspace[0] = 0.0; + st->paraspace[1] = 0.0; + st->paraspace[2] = 0.0; + st->paraspace[3] = 0.0; scin->lang = lang; @@ -594,21 +599,46 @@ void sc_interp_destroy(SCInterpreter *scin) } -static void set_padding(struct frame *fr, const char *opts) +static int parse_tuple(const char *a, float v[4]) { int nn; - float l, r, t, b; - nn = sscanf(opts, "%f,%f,%f,%f", &l, &r, &t, &b); + nn = sscanf(a, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]); if ( nn != 4 ) { - fprintf(stderr, "Invalid padding '%s'\n", opts); - return; + fprintf(stderr, "Invalid tuple '%s'\n", a); + return 1; } - fr->pad_l = l; - fr->pad_r = r; - fr->pad_t = t; - fr->pad_b = b; + return 0; +} + + +static void set_padding(struct frame *fr, const char *opts) +{ + float p[4]; + + if ( parse_tuple(opts, p) ) return; + + fr->pad_l = p[0]; + fr->pad_r = p[1]; + fr->pad_t = p[2]; + fr->pad_b = p[3]; +} + + +static void set_paraspace(SCInterpreter *scin, const char *opts) +{ + float p[4]; + struct sc_state *st = &scin->state[scin->j]; + + if ( parse_tuple(opts, p) ) return; + + st->paraspace[0] = p[0]; + st->paraspace[1] = p[1]; + st->paraspace[2] = p[2]; + st->paraspace[3] = p[3]; + + set_para_spacing(current_para(sc_interp_get_frame(scin)), p); } @@ -844,6 +874,7 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, PangoFontDescription *fontdesc; double *col; int just_closed = 0; + struct sc_state *st = &scin->state[scin->j]; /* Empty block? */ if ( text == NULL ) return 1; @@ -873,6 +904,7 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, if ( just_closed ) { Paragraph *para = last_open_para(fr); add_run(para, bl, start, 0, fontdesc, col); + set_para_spacing(para, st->paraspace); } close_last_paragraph(fr); start += 1; @@ -880,6 +912,7 @@ static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl, } else { Paragraph *para = last_open_para(fr); add_run(para, bl, start, len, fontdesc, col); + set_para_spacing(para, st->paraspace); start += len; just_closed = 0; } @@ -1070,6 +1103,12 @@ int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl) set_frame_bggrad(sc_interp_get_frame(scin), options, GRAD_VERT); + } else if ( strcmp(name, "paraspace") == 0 ) { + maybe_recurse_before(scin, child); + printf("Got paraspace\n"); + set_paraspace(scin, options); + maybe_recurse_after(scin, child); + } else if ( strcmp(name, "callback") == 0 ) { do_callback(scin, bl, options); @@ -1181,6 +1220,9 @@ void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl) set_frame_bggrad(sc_interp_get_frame(scin), options, GRAD_VERT); + } else if ( strcmp(name, "paraspace") == 0 ) { + set_paraspace(scin, options); + } bl = sc_block_next(bl); |