[cairo] drawing on and reusing an off-screen image surface

Peter Groves pdgroves at gmail.com
Sun Dec 2 23:31:52 PST 2007


Hi,

(Sorry if this is posted twice.)

I'm new to cairo (and gtk for that matter), and am having some trouble
understanding how to draw on and re-use an image buffer in a custom gtk
widget.  Generally, what my widget will do is create a complex cairo
drawing, rasterize it in some kind of image buffer, and then reuse the
rasterized image buffer as a background while some simple foreground
drawings are made in response to mouse movements. The widget will
therefore be repainted very quickly as the mouse moves across it, and 
I don't want to repaint the background from scratch each time.

Despite spending quite a bit of time with the docs and apis, I still
don't feel terribly confident I know what to do. Could someone take 
a look at this c-ish pseudo-code and tell me if it is the right basic 
cairo interactions? My main uncertainty is marked by (**). 
(I'm actually using the ruby bindings, but this pseudo code should 
hopefully be easily readable for this list.)

##at my application startup, draw the background and save it as 
##a cairo_pattern
startup() {
	background_surface = cairo_image_surface_create(...)
	background_ctx = cairo_create(background_surface)

	#do all the cairo drawings for the background
	my_draw_the_background_method(background_ctx)

	#this global variable will hopefully be a fully rendered version of 
	#the rasterized background image
	_background_pattern = cairo_pattern_create_for_surface(background_surface)
}

##now, inside my main re-paint function for a gtk drawing area 
##named 'widg', which will be called on expose_event and some other 
##events
repaint(widg){

	#get the cairo_t for the gtk widget
	gtk_widget_ctx = gdk_cairo_create(widg)

	#tell cairo to use the cached rasterized image as the "paint"
	cairo_set_source(gtk_widget_ctx, _background_pattern)

	#(**)paint the whole gtk_widget_ctx canvas with the image.  
	cairo_paint(gtk_widget_ctx)

	#do any additional drawings that occur each re-paint on top
	my_draw_the_foreground_method(gtk_widget_ctx)
}


Regarding (**), this is the step that most confuses me: when the call
to cairo_paint is made, will _background_pattern be re-rendered (from 
vector to raster form), or is the rasterized form created exactly once 
when cairo_pattern_create_for_surface(...) is called in startup()? 

More generally, when does the rasterization of a pattern made from
an image surface occur: when it's drawn, when it's converted to a 
pattern, or when it's displayed?

If the cached image surface *is* re-rendered each time it's painted
on the widget's cairo context, how can I render and store a copy of the
rasterized data in my startup method? How can I tell cairo to paint 
that rasterized form in my repaint method?

Any help is greatly appreciated.

Peter





More information about the cairo mailing list