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;
}