Re: cairo drawing commands to gdk_invalidate_region

I uploaded my solution that I gave the working name dovtk-lasso to github at:

On the one hand it works beautifully as it allows drawing dynamic overlays with cairo with very little overhead. On the other hand it still has some problems:
Have a look at the png file at github to see an example of a caliper like measuring tool that I made with dovtk-lasso. Again, the graphics is arbitrary, and could just as well be a rectangle, a cross hair, or whatever the user feels like.

Looking forward to comments.


On Tue, Aug 17, 2010 at 22:03, Federico Mena Quintero <federico ximian com> wrote:
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.



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