[cairo] Avoiding seams (again)
Timothée Lecomte
timothee.lecomte at ens.fr
Wed Mar 22 15:34:59 PST 2006
> On Wed, 22 Mar 2006 22:13:56 +0100 (CET), Timothée Lecomte wrote:
>>
>> Do you remember the thread about avoiding seams between paths a months
>> ago ?
>
> I do. I think it's an interesting class of problem.
>
>> - stroke each path
>> Good : gives expected result
>
> I'd like to disagree on that point. Stroking each shape will still
> introduce seams if there is transparency involved. And even with
> entirely opaque objects can result in "lumpiness" (that is,
> poor-quality antialiasing), on the border of the composite object,
> where multiple primitives meet.
I think I understand. These antialiasing problems are definitely more
complicated that I would have imagine.
>> - use CAIRO_OPERATOR_SATURATE
>> Good : no seam, reasonably fast
>
> Those are looking like some good characteristics to work from as a
> starting point.
Indeed, but remember that this is still sub-optimal as it implies a
separate context and drawing front-to-back...
>> Problem : have to draw front-to-back to a separate context whereas
>> gnuplot gives me the instructions back-to-front, so it adds some
>> overhead.
>> But I also get white lines artifacts.
>> See : http://tipote.free.fr/wxt-saturate2.png
>>
>> Do you have other ideas, or a solution to the artefacts problem with
>> CAIRO_OPERATOR_SATURATE ?
>
> It could be just a bug that we hadn't noticed before. I'm not sure
> that the SATURATE stuff has seen a lot of correctness testing yet.
>
> If you could replicate this behavior in as minimal a test case as
> possible, that would be very helpful.
Sure. You made me try with both the image surface and the xlib one
(through gtk_cairo_create(), and the artefacts only appear with the xlib
surface.
Here is a sample code (plot.cr is the main context, plot.current_xmax and
plot.currentymax are its width and height):
cairo_t *context;
cairo_surface_t *surface;
surface = cairo_surface_create_similar(cairo_get_target(plot.cr),
CAIRO_CONTENT_COLOR_ALPHA,
plot.current_xmax,
plot.current_ymax);
context = cairo_create(surface);
cairo_set_operator(context,CAIRO_OPERATOR_SATURATE);
cairo_move_to(context, 300, 200);
cairo_rel_line_to(context, 100, 0);
cairo_rel_line_to(context, 0, 100);
cairo_close_path(context);
cairo_set_source_rgb(context,0,0,0);
cairo_fill(context);
cairo_move_to(context, 250, 170);
cairo_rel_line_to(context, 100, 0);
cairo_rel_line_to(context, 0, 100);
cairo_close_path(context);
cairo_set_source_rgb(context,0,0,0.5);
cairo_fill(context);
cairo_move_to(context, 360, 200);
cairo_rel_line_to(context, 30, 0);
cairo_rel_line_to(context, 0, -40);
cairo_close_path(context);
cairo_set_source_rgb(context,1,0,0);
cairo_fill(context);
cairo_move_to(context, 400, 100);
cairo_rel_line_to(context, 100, 0);
cairo_rel_line_to(context, -100, 300);
cairo_close_path(context);
cairo_set_source_rgb(context,0,1,0);
cairo_fill(context);
cairo_move_to(context, 400, 300);
cairo_rel_line_to(context, -80, -80);
cairo_rel_line_to(context, 0, 100);
cairo_close_path(context);
cairo_set_source_rgb(context,0.6,0.4,0);
cairo_fill(context);
cairo_pattern_t *pattern = cairo_pattern_create_for_surface( surface );
cairo_destroy( context );
cairo_surface_destroy( surface );
cairo_set_source( plot.cr, pattern );
cairo_pattern_destroy( pattern );
cairo_paint(plot.cr);
Here is the results :
For the xlib surface : http://tipote.free.fr/wxt-saturate3.png
For the image surface : http://tipote.free.fr/wxt-saturate4.png
Notice the edges between the blue, back and brown triangles.
Best regards,
Timothée
More information about the cairo
mailing list