Seams with CAIRO_ANTIALIAS_FAST

[email protected] (Søren Sandmann)
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
The CAIRO_ANTIALIAS_FAST option uses a 2x2 sampling grid where each
sample has a weight of 64 when the depth of the mask is 8 bits.

This is problematic because the four samples then sum to 256, which
causes a seam a pixel is fully covered by a combination of independent
polygons.

The attached program demonstrates this. The blue rectangle is drawn as
four separate rectangles and the cross where they meet has a blue
channel of 0x74 where the rest of the rectangle is 0x73.

There are various fixes possible:

(a) Make ANTIALIAS_FAST use a 3x5 sampling grid. This is tempting
    because X Render already supports this antialiasing mode (rendering
    trapezoids to a 4 bit mask will use it).

(b) Make the weight of one of the samples 63 instead of 64. I don't know
    how difficult this will be in the tor22 rasterizer.

(c) Ignore it and document that cairo can't draw seamless polygons.

    Considering that the bug-seams.c test has been failing ever since
    the tor rasterizer was added, and that fixing that test will
    probably involve a performance hit from turning off analytical
    antialiasing, maybe this is the more honest way to go.


Soren

-- 
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
seams22.c (text/x-csrc, 2.4 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);

        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, 0, 0, 0, 1.0);
        cairo_fill (cr);

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

	cairo_set_source_rgba (cr, 0, 0, 0.45, 1);
        cairo_set_operator (cr, CAIRO_OPERATOR_ADD);

	cairo_rectangle (cr, 199.5, 149.5, 200, 150);
	cairo_fill (cr);

	cairo_rectangle (cr, 399.5, 149.5, 200, 150);
	cairo_fill (cr);

	cairo_rectangle (cr, 199.5, 299.5, 200, 150);
	cairo_fill (cr);

	cairo_rectangle (cr, 399.5, 299.5, 200, 150);
	cairo_fill (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.