[cairo] problem rotating svg
Russell Strong
rstrong at bigpond.net.au
Sat Apr 2 18:20:22 PST 2005
>On Fri, 01 Apr 2005 19:28:29 +1000, Russell Strong wrote:
>> I've tried rotating some SVG images and found that parts of the image
>> aren't behaving correctly. I'm not sure how to describe it except by
>> saying run the code and take a look. The file home.svg comes from
>> cairo-demo/cairo_snippets/data.
>>
>> Is it a bug or am I bone?
>
>Wow, that looks like a whopper of a bug. It appears that gradient
>patterns aren't behaving properly under rotation. The next thing to do
>would be to replicate the bug in a small C program, (which we can put
>into cairo/test to keep something like this from showing up again
>unnoticed).
>
>-Carl
I suspect that libsvg-cairo is doing something similar to the code below, which shows similar behaviour.
pat = cairo_pattern_create_linear(0.0,0.0,0.0,w/2);
cairo_pattern_add_color_stop (pat, 1, 0, 0, 0, 1);
cairo_pattern_add_color_stop (pat, 0, 1, 1, 1, 1);
cairo_rectangle (cr,0,0,w/2,h/2);
cairo_set_rgb_color (cr,0,0,0);
cairo_stroke(cr);
cairo_rectangle (cr, 0,0,w/2,h/2);
cairo_set_pattern (cr, pat);
cairo_translate(cr, w/2, h/2);
cairo_rotate(cr, angle);
cairo_fill (cr);
cairo_pattern_destroy(pat);
Here the translate and rotate operations are affecting the gradient, which I wouldn't have expected.
Is there some sort of problem with libsvg-cairo handling of gradients and matrices?
full code:
#include <gtk/gtk.h>
#include <gtkcairo.h>
float angle=0.0;
static void paint (GtkWidget *widget,cairo_t *cr,gpointer data)
{
gint w,h;
cairo_pattern_t *pat;
w = widget->allocation.width;
h = widget->allocation.height;
cairo_rectangle (cr, 0, 0, w, h);
cairo_set_rgb_color (cr, 1,1,1);
cairo_fill (cr);
pat = cairo_pattern_create_linear(0.0,0.0,0.0,w/2);
cairo_pattern_add_color_stop (pat, 1, 0, 0, 0, 1);
cairo_pattern_add_color_stop (pat, 0, 1, 1, 1, 1);
cairo_rectangle (cr,0,0,w/2,h/2);
cairo_set_rgb_color (cr,0,0,0);
cairo_stroke(cr);
cairo_rectangle (cr, 0,0,w/2,h/2);
cairo_set_pattern (cr, pat);
cairo_translate(cr, w/2, h/2);
cairo_rotate(cr, angle);
cairo_fill (cr);
cairo_pattern_destroy(pat);
}
static gint periodic(gpointer data)
{
GtkWidget *widget = GTK_WIDGET(data);
angle += 0.03;
gtk_widget_queue_draw(widget);
return TRUE;
}
gint main (gint argc, gchar *argv[])
{
GtkWidget *win;
GtkWidget *gtkcairo;
gtk_init (&argc, &argv);
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (win), "delete-event", G_CALLBACK (gtk_main_quit), NULL);
gtkcairo = gtk_cairo_new ();
gtk_widget_set_size_request (gtkcairo, 400, 400);
g_signal_connect (G_OBJECT (gtkcairo), "paint", G_CALLBACK (paint), NULL);
gtk_container_add (GTK_CONTAINER (win), gtkcairo);
gtk_widget_show_all (win);
g_timeout_add(50,periodic,gtkcairo);
gtk_main ();
return 0;
}
- Russell
More information about the cairo
mailing list