How To: Render 1bpp bitmaps with cairo



It took a couple days, but I finally pieced together the necessary steps.

The idea is to render a 1bpp bitmap either normally or selected (in the current background color on a rectangle painted with the current foreground color).

You may need to fiddle with the GtkStateFlags depending on what type of widget you are drawing on (widget may be in a state other than NORMAL).

If anyone has a more elegant solution, please feel free to show it off.

===================================================================

/*
 * The 'data' parameter is a GtkDrawingArea widget.
 */

static gboolean invert = TRUE;
static cairo_surface_t *s;

/*
 * Function type just to simplify the code.
 */
typedef void (*get_color_func_t)(GtkStyleContext *,GtkStateFlags,GdkRGBA *);

static void
invert_bitmap(GtkWidget *w, gpointer data)
{
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(data)));
    GtkStyleContext *ctx = gtk_widget_get_style_context(GTK_WIDGET(data));
    GdkRGBA c;
    get_color_func_t get_bg, get_fg;

    if (invert) {
        /*
* Display inverted form: background of rectangle in foreground color
         * and bitmap in background color.
         */
        get_bg = gtk_style_context_get_color;
        get_fg = gtk_style_context_get_background_color;
    } else {
        /*
         * Show normal bitmap while clearing the background behind it.
         */
        get_fg = gtk_style_context_get_color;
        get_bg = gtk_style_context_get_background_color;
    }

    (*get_bg)(ctx,GTK_STATE_FLAG_NORMAL,&c);
    cairo_set_source_rgb(cr,c.red,c.green,c.blue);
    cairo_rectangle(cr, 1, 1, 13, 22);
    cairo_fill(cr);

    (*get_fg)(ctx,GTK_STATE_FLAG_NORMAL,&c);
    cairo_set_source_rgb(cr,c.red,c.green,c.blue);
    cairo_mask_surface(cr,s,2.0,1.0);

    cairo_destroy(cr);
    invert = !invert;
}

--
Mark Leisher


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]