aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2014-09-20 23:49:51 +0200
committerThomas White <taw@bitwiz.org.uk>2014-09-20 23:49:51 +0200
commita2a27a077edc1028d93bf27471218221cd6405de (patch)
tree92f05a75ecad63f4f24ffa4322e50820f23ca8fe /src
parent38828312e6be39941a2f889b36441c5b42bd484a (diff)
Add gradient backgrounds
Diffstat (limited to 'src')
-rw-r--r--src/frame.h10
-rw-r--r--src/render.c51
-rw-r--r--src/sc_interp.c70
3 files changed, 122 insertions, 9 deletions
diff --git a/src/frame.h b/src/frame.h
index 791156d..e81197b 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -40,6 +40,14 @@ typedef enum
} LengthUnits;
+typedef enum
+{
+ GRAD_NONE,
+ GRAD_HORIZ,
+ GRAD_VERT
+} GradientType;
+
+
struct frame
{
struct frame **children;
@@ -66,6 +74,8 @@ struct frame
/* Background properties for this frame */
double bgcol[4];
+ double bgcol2[4];
+ GradientType grad;
/* True if this frame should be deleted on the next mouse click */
int empty;
diff --git a/src/render.c b/src/render.c
index db41402..598a40f 100644
--- a/src/render.c
+++ b/src/render.c
@@ -253,14 +253,57 @@ static void render_lines(struct frame *fr, cairo_t *cr, ImageStore *is,
}
-static int draw_frame(cairo_t *cr, struct frame *fr, ImageStore *is,
- enum is_size isz)
+static void do_background(cairo_t *cr, struct frame *fr)
{
+ cairo_pattern_t *patt = NULL;
+
cairo_new_path(cr);
cairo_rectangle(cr, 0.0, 0.0, fr->w, fr->h);
- cairo_set_source_rgba(cr, fr->bgcol[0], fr->bgcol[1], fr->bgcol[2],
- fr->bgcol[3]);
+
+ switch ( fr->grad ) {
+
+ case GRAD_NONE:
+ cairo_set_source_rgba(cr, fr->bgcol[0],
+ fr->bgcol[1],
+ fr->bgcol[2],
+ fr->bgcol[3]);
+ break;
+
+ case GRAD_VERT:
+ patt = cairo_pattern_create_linear(0.0, 0.0,
+ 0.0, fr->h);
+ cairo_pattern_add_color_stop_rgb(patt, 0.0, fr->bgcol[0],
+ fr->bgcol[1],
+ fr->bgcol[2]);
+ cairo_pattern_add_color_stop_rgb(patt, 1.0, fr->bgcol2[0],
+ fr->bgcol2[1],
+ fr->bgcol2[2]);
+ cairo_set_source(cr, patt);
+ break;
+
+ case GRAD_HORIZ:
+ patt = cairo_pattern_create_linear(0.0, 0.0,
+ fr->w, 0.0);
+ cairo_pattern_add_color_stop_rgb(patt, 0.0, fr->bgcol[0],
+ fr->bgcol[1],
+ fr->bgcol[2]);
+ cairo_pattern_add_color_stop_rgb(patt, 1.0, fr->bgcol2[0],
+ fr->bgcol2[1],
+ fr->bgcol2[2]);
+ cairo_set_source(cr, patt);
+ break;
+
+ }
+
cairo_fill(cr);
+ if ( patt != NULL ) cairo_pattern_destroy(patt);
+}
+
+
+static int draw_frame(cairo_t *cr, struct frame *fr, ImageStore *is,
+ enum is_size isz)
+{
+ do_background(cr, fr);
if ( fr->trouble ) {
cairo_new_path(cr);
diff --git a/src/sc_interp.c b/src/sc_interp.c
index 525b54a..646a132 100644
--- a/src/sc_interp.c
+++ b/src/sc_interp.c
@@ -236,6 +236,48 @@ static void set_frame_bgcolour(struct frame *fr, const char *colour)
fr->bgcol[1] = col.green;
fr->bgcol[2] = col.blue;
fr->bgcol[3] = col.alpha;
+ fr->grad = GRAD_NONE;
+}
+
+
+static void set_frame_bggrad(struct frame *fr, const char *options,
+ GradientType grad)
+{
+ GdkRGBA col1, col2;
+ char *n2;
+ char *optcopy = strdup(options);
+
+ if ( fr == NULL ) return;
+
+ if ( options == NULL ) {
+ fprintf(stderr, "Invalid bg gradient spec '%s'\n", options);
+ return;
+ }
+
+ n2 = strchr(optcopy, ',');
+ if ( n2 == NULL ) {
+ fprintf(stderr, "Invalid bg gradient spec '%s'\n", options);
+ return;
+ }
+
+ n2[0] = '\0';
+
+ gdk_rgba_parse(&col1, optcopy);
+ gdk_rgba_parse(&col2, &n2[1]);
+
+ fr->bgcol[0] = col1.red;
+ fr->bgcol[1] = col1.green;
+ fr->bgcol[2] = col1.blue;
+ fr->bgcol[3] = col1.alpha;
+
+ fr->bgcol2[0] = col2.red;
+ fr->bgcol2[1] = col2.green;
+ fr->bgcol2[2] = col2.blue;
+ fr->bgcol2[3] = col2.alpha;
+
+ fr->grad = grad;
+
+ free(optcopy);
}
@@ -596,11 +638,6 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
scin->pc, bl, contents, scin->lang, 1,
scin);
- } else if ( strcmp(name, "bgcol") == 0 ) {
- maybe_recurse_before(scin, child);
- set_frame_bgcolour(sc_interp_get_frame(scin), options);
- maybe_recurse_after(scin, child);
-
} else if ( strcmp(name, "image")==0 ) {
double w, h;
char *filename;
@@ -755,6 +792,20 @@ int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl)
maybe_recurse_before(scin, child);
maybe_recurse_after(scin, child);
+ } else if ( strcmp(name, "bgcol") == 0 ) {
+ maybe_recurse_before(scin, child);
+ set_frame_bgcolour(sc_interp_get_frame(scin), options);
+ maybe_recurse_after(scin, child);
+
+ } else if ( strcmp(name, "bggradh") == 0 ) {
+ set_frame_bggrad(sc_interp_get_frame(scin), options,
+ GRAD_HORIZ);
+
+ } else if ( strcmp(name, "bggradv") == 0 ) {
+ set_frame_bggrad(sc_interp_get_frame(scin), options,
+ GRAD_VERT);
+
+
} else {
//fprintf(stderr, "Don't know what to do with this:\n");
@@ -854,6 +905,15 @@ void sc_interp_run_stylesheet(SCInterpreter *scin, SCBlock *bl)
} else if ( strcmp(name, "bgcol") == 0 ) {
set_frame_bgcolour(sc_interp_get_frame(scin), options);
+
+ } else if ( strcmp(name, "bggradh") == 0 ) {
+ set_frame_bggrad(sc_interp_get_frame(scin), options,
+ GRAD_HORIZ);
+
+ } else if ( strcmp(name, "bggradv") == 0 ) {
+ set_frame_bggrad(sc_interp_get_frame(scin), options,
+ GRAD_VERT);
+
}
bl = sc_block_next(bl);