diff --git a/src/draw.c b/src/draw.c index 14dfd8b..931f36c 100644 --- a/src/draw.c +++ b/src/draw.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "dunst.h" #include "icon.h" @@ -33,6 +34,8 @@ struct window_x11 *win; PangoFontDescription *pango_fdesc; +#define UINT_MAX_N(bits) ((1 << bits) - 1) + void draw_setup(void) { x_setup(); @@ -41,12 +44,16 @@ void draw_setup(void) pango_fdesc = pango_font_description_from_string(settings.font); } -static struct color hex_to_color(int hexValue) +static struct color hex_to_color(uint32_t hexValue, int dpc) { + const int bpc = 4 * dpc; + const unsigned single_max = UINT_MAX_N(bpc); + struct color ret; - ret.r = ((hexValue >> 16) & 0xFF) / 255.0; - ret.g = ((hexValue >> 8) & 0xFF) / 255.0; - ret.b = ((hexValue) & 0xFF) / 255.0; + ret.r = ((hexValue >> 3 * bpc) & single_max) / (double)single_max; + ret.g = ((hexValue >> 2 * bpc) & single_max) / (double)single_max; + ret.b = ((hexValue >> 1 * bpc) & single_max) / (double)single_max; + ret.a = ((hexValue) & single_max) / (double)single_max; return ret; } @@ -54,15 +61,24 @@ static struct color hex_to_color(int hexValue) static struct color string_to_color(const char *str) { char *end; - long int val = strtol(str+1, &end, 16); - if (*end != '\0' && *(end+1) != '\0') { + uint_fast32_t val = strtoul(str+1, &end, 16); + if (end[0] != '\0' && end[1] != '\0') { LOG_W("Invalid color string: '%s'", str); } - return hex_to_color(val); + switch (end - (str+1)) { + case 3: return hex_to_color((val << 4) | 0xF, 1); + case 6: return hex_to_color((val << 8) | 0xFF, 2); + case 4: return hex_to_color(val, 1); + case 8: return hex_to_color(val, 2); + } + + /* return black on error */ + LOG_W("Invalid color string: '%s'", str); + return hex_to_color(0xF, 1); } -static double color_apply_delta(double base, double delta) +static inline double color_apply_delta(double base, double delta) { base += delta; if (base > 1) @@ -481,6 +497,12 @@ static cairo_surface_t *render_background(cairo_surface_t *srf, cairo_t *c = cairo_create(srf); + /* stroke area doesn't intersect with main area */ + cairo_set_fill_rule(c, CAIRO_FILL_RULE_EVEN_ODD); + + /* for correct combination of adjacent areas */ + cairo_set_operator(c, CAIRO_OPERATOR_ADD); + if (first) height += settings.frame_width; if (last) @@ -488,11 +510,8 @@ static cairo_surface_t *render_background(cairo_surface_t *srf, else height += settings.separator_height; - if (settings.frame_width > 0) - { - cairo_set_source_rgb(c, cl->frame.r, cl->frame.g, cl->frame.b); + if (settings.frame_width > 0) { draw_rounded_rect(c, x, y, width, height, corner_radius, first, last); - cairo_fill(c); /* adding frame */ x += settings.frame_width; @@ -509,17 +528,23 @@ static cairo_surface_t *render_background(cairo_surface_t *srf, height -= settings.separator_height; radius_int = frame_internal_radius (corner_radius, settings.frame_width, height); + + draw_rounded_rect(c, x, y, width, height, radius_int, first, last); + cairo_set_source_rgba(c, cl->frame.r, cl->frame.g, cl->frame.b, cl->frame.a); + cairo_fill(c); } - cairo_set_source_rgb(c, cl->bg.r, cl->bg.g, cl->bg.b); draw_rounded_rect(c, x, y, width, height, radius_int, first, last); + cairo_set_source_rgba(c, cl->bg.r, cl->bg.g, cl->bg.b, cl->bg.a); cairo_fill(c); + cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); + if ( settings.sep_color.type != SEP_FRAME && settings.separator_height > 0 && !last) { struct color sep_color = layout_get_sepcolor(cl, cl_next); - cairo_set_source_rgb(c, sep_color.r, sep_color.g, sep_color.b); + cairo_set_source_rgba(c, sep_color.r, sep_color.g, sep_color.b, sep_color.a); cairo_rectangle(c, settings.frame_width, y + height, width, settings.separator_height); @@ -561,7 +586,7 @@ static void render_content(cairo_t *c, struct colored_layout *cl, int width) } cairo_move_to(c, text_x, text_y); - cairo_set_source_rgb(c, cl->fg.r, cl->fg.g, cl->fg.b); + cairo_set_source_rgba(c, cl->fg.r, cl->fg.g, cl->fg.b, cl->fg.a); pango_cairo_update_layout(c, cl->l); pango_cairo_show_layout(c, cl->l); diff --git a/src/x11/x.h b/src/x11/x.h index 3ed21e3..9874b7f 100644 --- a/src/x11/x.h +++ b/src/x11/x.h @@ -44,6 +44,7 @@ struct color { double r; double g; double b; + double a; }; extern struct x_context xctx;