From a2a27a077edc1028d93bf27471218221cd6405de Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 20 Sep 2014 23:49:51 +0200 Subject: Add gradient backgrounds --- src/frame.h | 10 +++++++++ src/render.c | 51 +++++++++++++++++++++++++++++++++++++---- src/sc_interp.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 122 insertions(+), 9 deletions(-) (limited to 'src') 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); -- cgit v1.2.3