aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2016-05-02 00:01:18 +0200
committerThomas White <taw@bitwiz.org.uk>2016-05-02 00:01:18 +0200
commitd66afeb74fed4be680cc56ca5c0fb7fd0c1fa53c (patch)
treec5c75e8d335aaf422e034bf20e5bb42efa53ea13
parent75967f41675ca5f4c9112460b67a2e77733eb1e4 (diff)
Paragraph spacing
-rw-r--r--src/frame.c38
-rw-r--r--src/frame.h3
-rw-r--r--src/narrative_window.c4
-rw-r--r--src/render.c5
-rw-r--r--src/sc_interp.c60
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);