Re: Horizontal artifacts rendering to an image surface

[email protected] (Søren Sandmann)
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
Floyd May <[email protected]> writes:

> I've been able to boil this down to a reproducible, small case.
> Basically, two four-point polygons where one edge from each is
> collinear.  Using even-odd rendering, I'm getting these artifacts:
>
> http://imagebin.org/222354
>
> Again, this is based on v 1.10.2, on Windows (both x86 and x64 exhibit
> the issue), based on a recent download of GTK+ binaries.
>
> Here is C# source (using Mono.Cairo; should be able to adapt to C code
> relatively easily):

FWIW, here is a C variant that shows the same artefact and also
demonstrates that it doesn't happen with the X backend. (To use the X
backend, set the "const int image" variable to 0).


Soren

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
artefacts.c (text/x-csrc, 2.6 KB)
#include <math.h>
#include <gtk/gtk.h>
#include <stdio.h>

static void
path_quad (cairo_t *cr,
           double x1, double y1, double x2, double y2,
           double x3, double y3, double x4, double y4)
{
    cairo_move_to (cr, x1, y1);
    cairo_line_to (cr, x2, y2);
    cairo_line_to (cr, x3, y3);
    cairo_line_to (cr, x4, y4);
    cairo_close_path (cr);
}

const int image = 1;

static gboolean
on_expose (GtkWidget *widget, GdkEvent *event, gpointer data)
{
    if (GTK_WIDGET_DRAWABLE (widget))
    {
        cairo_t *cr;
        int w, h;
        cairo_surface_t *surface;

        gdk_drawable_get_size (widget->window, &w, &h);
	printf ("size: %d %d\n", w, h);

        if (image)
        {
            surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
            cr = cairo_create (surface);
        }
        else
        {
            cr = gdk_cairo_create (widget->window);
        }

        cairo_rectangle (cr, 0, 0, w, h);
        cairo_set_source_rgba (cr, 1, 1, 1, 1.0);
        cairo_fill (cr);

	cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
	
        cairo_push_group (cr);

        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);

	path_quad (cr,
		   448.948314981535, 264.938083162531,
		   448.51546072308, 220.797386273742,
		   530, 220,
		   561.332719124854, 261.581040261313);

        path_quad (cr,
                   339.794010419399, 236.296868257225,
		   346.503195904195, 229.764422696084,
		   448.474225856364, 216.590856667608,
		   448.948314981535, 264.938083162531);

	cairo_set_source_rgb (cr, 0, 0.5, 1);
	cairo_fill_preserve (cr);
	cairo_set_source_rgb (cr, 0, 0, 0);
	cairo_stroke (cr);

        cairo_pop_group_to_source (cr);

        cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
        cairo_paint (cr);

        cairo_destroy (cr);

        if (image)
        {
            cr = gdk_cairo_create (widget->window);

            cairo_set_source_surface (cr, surface, 0, 0);

            cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

            cairo_paint (cr);

            cairo_destroy (cr);
        }
    }

    return TRUE;
}

int
main (int argc, char **argv)
{
    GtkWindow *window;
    GtkDrawingArea *area;

    gtk_init (&argc, &argv);

    window = GTK_WINDOW  (gtk_window_new (GTK_WINDOW_TOPLEVEL));
    area = GTK_DRAWING_AREA (gtk_drawing_area_new ());

    gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (area));

    gtk_window_set_default_size (window, 800, 600);

    gtk_widget_show_all (GTK_WIDGET (window));

    g_signal_connect (area, "expose_event", G_CALLBACK (on_expose), NULL);

    gtk_main ();
    return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.