[cairo] Drawing a sequence of line segments

Uli Schlachter psychon at znc.in
Tue Jun 3 06:48:17 PDT 2014


On 03.06.2014 13:45, ax487 wrote:
> *bump*
> I actually put quite some work into the pastebin example.

$ gcc -Wall -Wextra t.c $(pkg-config --cflags --libs gtk+-3.0 )
t.c: In function ‘invalidate_all’:
t.c:21:37: error: ‘GtkWidget’ has no member named ‘window’
     gdk_window_invalidate_rect(darea->window, &rect, TRUE);
[and lots of other errors which I guess all are due to GTK+ 2 vs GTK+ 3]

> Doesn't anyone
> have an idea how to interpolate between the full redraw and the lazy
> variant?
> On 29.05.2014 13:16, ax487 wrote:
>> Hello all,
>> I am using cairo to draw a stroke, that is a sequence of line segments,
>> onto a canvas, which is represented as a cairo_surface_t* internally.
>> The canvas is used in a Gtk+ application, the stroke is extended
>> whenever the mouse moves. Obviously, the redraw needs to be fast enough
>> such that there is no visible lag. A minimal example is here:
>> http://pastebin.com/RtaPajcU
>> I have tried the following approaches:
>> 1: Redraw the entire stroke whenever the mouse moves. This works
>> correctly apart from the fact that there is a lag which increases as
>> more points are drawn.
>> 2: Only draw the stroke between the last two points whenever the mouse
>> moves. This is noticeably faster but the drawing is incorrect: Pixels
>> are repeatedly overdrawn so the alpha value increases along certain
>> paths of the stroke.
>> I would like to go for fast and correct. Any ideas?

3. Create a CAIRO_FORMAT_A1 (or A8) intermediate surface to which you draw your
lines as you do with approach (2). Then use cairo_mask_surface() to get this
content to your target surface.

The intermediate surface is drawn to opaquely (with alpha = 1.0) and only for
cairo_mask_surface() do you use your solid source with alpha = 0.2.

Also, you don't need invalidate_all(). You only need to invalidate the bounding
rectangle between the previous and the newest point (plus 5 pixels of additional
space in all directions since you are using a line width of 5 pixels). That way
the actual redraw should become a little faster, too.

"Every once in a while, declare peace. It confuses the hell out of your enemies"
 - 79th Rule of Acquisition

More information about the cairo mailing list