[cairo] Howto draw ontop of a surface buffer
Daniel Bessler
daniel.bessler at gmx.net
Wed Jan 24 09:02:17 PST 2007
Hi there!
I am coding since some time on kiba-dock (a gnome dock based on Kristian
Høgsberg physics engine akamaru)
I integrated some days ago glitz support. before every icon on the dock had
its own window, and i drawed the surface buffer, with the SOURCE operator on
a offscreen pixmap, then i was able to use the ATOP operator for prelighting
or blending only the content of the surface buffer. Now i use only one big
surface for drawing and i draw the surface buffer with the OVER operator on
the drawing surface, surely prelight and blending doesnt work anymore with
the ATOP operator, it paints on all previosly rendered icons and the dock. I
didnt found a solution, in all examples i found that the prelight on a bigger
surface was handled by creating a rectangle and then calling cairo_fill, but
i only wanna draw ontop of the surface buffer, and i dont wanna redraw the
icon, what is the proper way to solve this problem?
The only workaround i can imagine is to create a surface, paint the surface
buffer with the SOURCE operator on it, then i can prelight the icon with the
ATOP operator, and then i paint the newly created surface with the OVER
operator on the mainsurface, but maybe there is a better way?
here are some small code snippets:
//rectangle solution
/* draws icon */
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_set_source_surface (cairo_context, object->background_surface, offset,
offset);
cairo_paint_with_alpha (cairo_context, launcher_icon->blend_alpha);
/* draw prelight */
if (object->prelight || !launcher_icon->running)
{
cairo_save (cairo_context);
cairo_set_operator (cairo_context, CAIRO_OPERATOR_ATOP);
cairo_rectangle (cairo_context, 0, 0, object->width, object->height);
convert_color (dgconf->prelight_color, &r, &g, &b);
cairo_set_source_rgba (cairo_context, r, g, b, dgconf->prelight_alpha);
cairo_fill (cairo_context);
cairo_restore (cairo_context);
}
//workaround with surface for every icon (seems to work, but its causing heavy
cpu load)
/* create surface */
surface = cairo_surface_create_similar (cairo_get_target (cairo_context),
CAIRO_CONTENT_COLOR_ALPHA, object->width, object->height);
cr = cairo_create (surface);
cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 0.0f);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_paint (cr);
/* draw icon on new surface */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface (cr, object->background_surface, offset, offset);
cairo_paint_with_alpha (cr, launcher_icon->blend_alpha);
/* draw prelight on new surface */
if (object->prelight || !launcher_icon->running)
{
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_ATOP);
convert_color (dgconf->prelight_color, &r, &g, &b);
cairo_set_source_rgba (cr, r, g, b, dgconf->prelight_alpha);
cairo_paint (cr);
cairo_restore (cr);
}
cairo_destroy (cr);
/* draw new surface on main context */
cairo_set_source_surface (cairo_context, surface, .0, .0);
cairo_paint (cairo_context);
cairo_surface_destroy (surface);
regards
danielb
More information about the cairo
mailing list