Re: cairo drawing commands to gdk_invalidate_region



On Tue, 2010-08-17 at 10:35 +0300, Dov Grobgeld wrote:
> Assume I have a routine:
> 
>     int draw(cairo_t *cr)
> 
> used to draw an overlay in a GdkWindow. 
> 
> In order to minimize redrawing, I would like to get the minimal (up to
> some accuracy to be determined) set of GdkRegion's that encompasses
> all the drawing of draw(). 

You may have a different case, but let me tell you about a cute trick I
had to do for iogrind [1].

One of iogrind's displays is essentially a point-cloud on which you move
a crosshair with the mouse:

  +---------------------+
  |   .   . | . .. . . .|
  | .   . . |.. . . .  .|
  |---------+-----------|
  |..  .. . |...  . . . |
  |   .   . |. . .. ..  |
  +---------------------+

The crosshair spans the whole width and height of the widget.  Drawing
the points is expensive, as there may be thousands of them.  With each
mouse motion event, you must repaint the crosshair.

My solution went like this:

1. The widget keeps a GdkPixmap where it draws the point-cloud at
startup.  The points don't move (thankfully), so that pixmap is
basically read-only after initialization.

2. My motion-notify handler does this:

    invalidate_vertical_line (w->cursor_x);
    invalidate_horizontal_line (w->cursor_y);
    w->cursor_x = event->x;
    w->cursor_y = event->y;
    invalidate_vertical_line (w->cursor_x);
    invalidate_horizontal_line (w->cursor_y);

3. My expose handler does this:

   bitblt (w->pixmap_with_points, widget->window);
   paint_vertical_line (w->cursor_x);
   paint_horizontal_line (w->cursor_y);

So, repaints are very fast as I can avoid regenerating the points; I
basically just paint the crosshair and that's it.

If your drawing can be done with mostly-static contents and an
occasional rubberband rectangle, this is a good way to do it.

[1] http://live.gnome.org/iogrind

  Federico




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