[cairo] ImageSurface Rendering Problems

Robert Gibbs gibbsrc at gmail.com
Thu Aug 10 18:37:08 PDT 2006


I am having trouble rendering an ImageSurface to an X11 display.  My problem
seems to be with only certain sizes and may possibly be related to my
graphics card and driver.

In the code below, I took the "Image" snippet from the cairo-demo package
and broke it out into a simple program.

I then took the png file "romedalen.png" and sc.aled and saved it using Gimp
such that I had a total of five files of pixel sizes 100x100,
256x192(original size), 300x300, 400x300, and 400x400.

(BTW, the cairo_snippets_gtk program is presently broken due to API
changes.  I have included patches at the bottom of this message.)

I found that some files would display properly and some would not.  I also
found that it seemed to be related to the display and graphics card.  Here
are the results:

ATI Radeon 9000 with dual screen using ati driver:
screen 0: 1400x1050
works: 256x192, 100x100,
doesn't work: 400x400, 300x300, 400x300

screen 1: 1600x1200
works: 256x192, 400x400, 100x100
doesn't work: 300x300, 400x300

NVIDIA on  1280x1024 using nvidia driver
works: 100x100, 256x192, 300x300, 400x300, 400x400
doesn't work:

I get the same results with cairo-1.0.4 and cairo-1.2.0.
Can anyone tell me what is wrong?  Is this a cairo bug?

Thanks
Bob Gibbs


/*********************** START SIMPLE PROGRAM ***************************/
#include <math.h>
#include <cairo.h>
#include <gtk/gtk.h>

/*cc `pkg-config gtk+-2.0 --cflags --libs` test-png.c */

#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 400

static cairo_surface_t *surface;

static void
create_surface()
{
        surface = cairo_image_surface_create_from_png ("romedalen5.png");
}

static void
snippet_normalize (cairo_t *cr, double width, double height)
{
    cairo_scale (cr, width, height);
    cairo_set_line_width (cr, 0.04);
}

static void
do_blit(cairo_t *cr)
{
        int w, h;

        snippet_normalize (cr, WINDOW_WIDTH, WINDOW_HEIGHT);

        w = cairo_image_surface_get_width (surface);
        h = cairo_image_surface_get_height (surface);
        printf("w=%d, h=%d\n", w, h);

        cairo_translate (cr, 0.5, 0.5);
        cairo_rotate (cr, 45* M_PI/180);
        cairo_scale  (cr, 1.0/w, 1.0/h);
        cairo_translate (cr, -0.5*w, -0.5*h);

        cairo_set_source_surface (cr, surface, 0, 0);
        //cairo_pattern_set_extend(cairo_get_source(cr),
CAIRO_EXTEND_REPEAT);
        cairo_paint (cr);
}

static void
paint(GtkWidget *w, GdkEvent *event)
{
        cairo_t *c;

        c = gdk_cairo_create(w->window);
        do_blit(c);
        cairo_destroy(c);
}

int
main(int argc, char **argv)
{
        GtkWidget *w, *da;

        create_surface();

        gtk_init(&argc, &argv);
        w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        da = gtk_drawing_area_new();
        gtk_widget_set_size_request(w, WINDOW_WIDTH, WINDOW_HEIGHT);
        g_signal_connect(da, "expose-event", G_CALLBACK(paint), NULL);
        gtk_container_add(GTK_CONTAINER(w), da);
        gtk_widget_show_all(w);
        gtk_main();
        return 0;
}
/*********************** END SIMPLE PROGRAM ***************************/


PATCHES:

Index: cairo_snippets_gtk.c
===================================================================
RCS file: /cvs/cairo/cairo-demo/cairo_snippets/cairo_snippets_gtk.c,v
retrieving revision 1.4
diff -a -u -r1.4 cairo_snippets_gtk.c
--- cairo_snippets_gtk.c        11 Jan 2005 22:38:03 -0000      1.4
+++ cairo_snippets_gtk.c        11 Aug 2006 01:06:37 -0000
@@ -3,7 +3,6 @@
  */

 #include "snippets.h"
-#include <gtkcairo.h>
 #include <gtk/gtk.h>
 #include <stdio.h>

@@ -13,15 +12,19 @@

 static void
 paint (GtkWidget *widget,
-        cairo_t   *cr,
-        void      *data)
+        GdkEvent *event)
 {
+    cairo_t *cr;
+
+    cr = gdk_cairo_create(widget->window);
+
     gint width = widget->allocation.width ;
     gint height = widget->allocation.height;

     cairo_save (cr);
       snippet_do (cr, current_snippet, width, height);
     cairo_restore (cr);
+    cairo_destroy(cr);
 }

 static void
@@ -123,10 +126,10 @@
     hpaned = gtk_hpaned_new ();
     vpaned = gtk_vpaned_new ();

-    gtkcairo = gtk_cairo_new ();
+    gtkcairo = gtk_drawing_area_new ();
     gtk_widget_set_usize (GTK_WIDGET (gtkcairo), 256, 256);

-    g_signal_connect (G_OBJECT (gtkcairo), "paint",
+    g_signal_connect (G_OBJECT (gtkcairo), "expose-event",
                       G_CALLBACK (paint), NULL);

     source_view = create_source_view ();
Index: configure.ac
===================================================================
RCS file: /cvs/cairo/cairo-demo/cairo_snippets/configure.ac,v
retrieving revision 1.3
diff -a -u -r1.3 configure.ac
--- configure.ac        24 Feb 2005 16:21:01 -0000      1.3
+++ configure.ac        11 Aug 2006 01:06:37 -0000
@@ -9,7 +9,7 @@
 AC_STDC_HEADERS

 PKG_CHECK_MODULES(SNIPPETS, libpng libsvg-cairo >= 0.1.2 cairo >= 0.3.0)
-PKG_CHECK_MODULES(GTKCAIRO, gtkcairo, enable_gtkcairo=yes,
enable_gtkcairo=no)
+PKG_CHECK_MODULES(GTKCAIRO, gtk+- 2.0 >= 2.8, enable_gtkcairo=yes,
enable_gtkcairo=no)

 AM_CONDITIONAL(BUILD_GTKCAIRO, test x$enable_gtkcairo = xyes)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freedesktop.org/archives/cairo/attachments/20060810/ff63c300/attachment-0001.html


More information about the cairo mailing list