From 46bcc55f6f67cae6c52f2e93e549d803761a8e51 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ingo=20B=C3=BCrk?= Date: Wed, 14 Oct 2015 19:03:05 +0200 Subject: [PATCH] Extract cairo_clear_surface. This commit refactors the i3bar drawing code to also define an abstraction function for clearing a surface. This is needed to fully abstract i3bar/xcb.c's drawing code so that we can introduce a switch to easily exchange the underlying drawing mechanism. --- i3bar/include/cairo_util.h | 7 +++++++ i3bar/src/cairo_util.c | 23 +++++++++++++++++++++++ i3bar/src/xcb.c | 14 ++------------ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/i3bar/include/cairo_util.h b/i3bar/include/cairo_util.h index 3e4ebec4..fe2d06ff 100644 --- a/i3bar/include/cairo_util.h +++ b/i3bar/include/cairo_util.h @@ -89,6 +89,13 @@ void cairo_draw_text(i3String *text, surface_t *surface, color_t fg_color, color */ void cairo_draw_rectangle(surface_t *surface, color_t color, double x, double y, double w, double h); +/** + * Clears a surface with the given color. + * Note that the drawing is done using CAIRO_OPERATOR_SOURCE. + * + */ +void cairo_clear_surface(surface_t *surface, color_t color); + /** * Copies a surface onto another surface. * Note that the drawing is done using CAIRO_OPERATOR_SOURCE. diff --git a/i3bar/src/cairo_util.c b/i3bar/src/cairo_util.c index 98c129b9..2cec76d6 100644 --- a/i3bar/src/cairo_util.c +++ b/i3bar/src/cairo_util.c @@ -114,6 +114,29 @@ void cairo_draw_rectangle(surface_t *surface, color_t color, double x, double y, cairo_restore(surface->cr); } +/** + * Clears a surface with the given color. + * Note that the drawing is done using CAIRO_OPERATOR_SOURCE. + * + */ +void cairo_clear_surface(surface_t *surface, color_t color) { + cairo_save(surface->cr); + + /* Using the SOURCE operator will copy both color and alpha information directly + * onto the surface rather than blending it. This is a bit more efficient and + * allows better color control for the user when using opacity. */ + cairo_set_operator(surface->cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_color(surface, color); + + cairo_paint(surface->cr); + + /* Make sure we flush the surface for any text drawing operations that could follow. + * Since we support drawing text via XCB, we need this. */ + CAIRO_SURFACE_FLUSH(surface->surface); + + cairo_restore(surface->cr); +} + /** * Copies a surface onto another surface. * Note that the drawing is done using CAIRO_OPERATOR_SOURCE. diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index aa7b816c..3b3836c1 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -244,12 +244,7 @@ void refresh_statusline(bool use_short_text) { realloc_sl_buffer(); /* Clear the statusline pixmap. */ - cairo_save(statusline_surface.cr); - cairo_set_source_color(&statusline_surface, colors.bar_bg); - cairo_set_operator(statusline_surface.cr, CAIRO_OPERATOR_SOURCE); - cairo_paint(statusline_surface.cr); - CAIRO_SURFACE_FLUSH(statusline_surface.surface); - cairo_restore(statusline_surface.cr); + cairo_clear_surface(&statusline_surface, colors.bar_bg); /* Draw the text of each block. */ uint32_t x = 0; @@ -1797,12 +1792,7 @@ void draw_bars(bool unhide) { } /* First things first: clear the backbuffer */ - cairo_save(outputs_walk->buffer.cr); - cairo_set_source_color(&(outputs_walk->buffer), colors.bar_bg); - cairo_set_operator(outputs_walk->buffer.cr, CAIRO_OPERATOR_SOURCE); - cairo_paint(outputs_walk->buffer.cr); - CAIRO_SURFACE_FLUSH(outputs_walk->buffer.surface); - cairo_restore(outputs_walk->buffer.cr); + cairo_clear_surface(&(outputs_walk->buffer), colors.bar_bg); if (!config.disable_ws) { i3_ws *ws_walk; -- 2.39.5