[cairo] cairo/gdk + clipping

Dov Grobgeld dov.grobgeld at gmail.com
Wed Aug 18 23:31:50 PDT 2010

If you keep your visible rectangles in a list you only need to call
gdk_widget_draw_area() with coordinates of a rectangle either added or
removed from your list. When adding you need to redraw the new area, and
when removing you need to "heal" the area that the rectangle previously
occupied. In your expose event you should clip your cairo drawing to the
area that is being exposed, and then loop and draw all rectangles in your
list. (I'm still wondering whether it is faster to manually check whether
the bounding box of the drawn objects fall within the bounding box of the
exposed area, or simply to rely on cairo doing it efficiently.)

Hopefully this will be fast enough.


On Wed, Aug 18, 2010 at 16:49, Benjamin Otte <otte at redhat.com> wrote:

> A Gtk widget's expose event always prompts you to repaint all of the
> region provided completely. You cannot assume anything about what you
> previously rendered.
> So if you render everything with Cairo, what you usually want to for
> creating your Cairo context is run code like this:
> cr = gdk_cairo_create (event->window);
> gdk_cairo_region (cr, event->region);
> cairo_clip (cr);
> Then you end up with a region that is properly clipped to the area that
> actually needs to be repainted. But of course, you will still need to
> paint everything in that given region.
> Cairo will however be smart enough to ignore rectangles that are outside
> of that region automatically, because they are clipped.
> If that still doesn't turn out to be fast enough, you could maintain a
> backing surface that you update and then just cairo_paint() to the
> screen in the expose event. But I would be surprised if a few rectangles
> caused any trouble.
> Benjamin
> On Wed, 2010-08-18 at 11:46 +0100, James Morris wrote:
> > Hi,
> >
> > I'm having some difficulty with understanding cairo and gtk and clipping.
> >
> > I need to draw rectangles that appear and disappear over time. I've
> > setup a gtk timeout which calls gtk_queue_draw on the window and the
> > drawable in use by cairo as the surface - this provokes my expose
> > event handler to be called. Here I call gdk_cairo_create, do my
> > drawing, and then cairo_destroy.
> >
> > I asked about this on gtk-app-devel and had some responses but still
> > seem to be stuck with erasure of what has been previously drawn each
> > time something new is drawn (ie a new rectangle appears after some
> > period of time has elapsed, drawing it erases all past rectangles).
> >
> > The solution seemed to be clipping. So I clip_preserve the rectangle
> > and then fill it, but still everything else is erased.
> >
> > It was suggested I could dispense with the timeout. I don't think so,
> > as the rectangles are dictated by another thread which only provides
> > the dimensions of a rectangle when it should appear/disappear (getting
> > this information in advance is not possible).
> >
> > My first working approach was to store in a list all the rectangles
> > current in existence (and remove them when the disappear). Then on
> > each call to the expose event handler the surface background and every
> > rectangle would be drawn. With the timeout set at 33ms, and on average
> > 200 rectangles appearing/disappearing per second, this approach proved
> > too expensive of CPU resources. I decided then to try GDK and
> > performance was a *lot* better and satisfactory, but then I discovered
> > the GDK drawing and GDKGC functions are deprecated, hence a return to
> > Cairo.
> >
> > Can anyone advise here please?
> >
> > Cheers,
> > James
> > --
> > cairo mailing list
> > cairo at cairographics.org
> > http://lists.cairographics.org/mailman/listinfo/cairo
> --
> cairo mailing list
> cairo at cairographics.org
> http://lists.cairographics.org/mailman/listinfo/cairo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20100819/ce645e5e/attachment-0001.html>

More information about the cairo mailing list