2016-04-06 11 views
1

Ich arbeite an einer GtkDrawingArea, die in dem Expose-Ereignis einen Abschnitt eines Pixbuf in einer gekachelten Weise zeichnet. Der Kacheltyp variiert - abhängig vom Quellbild; es kann orthogonal, isometrisch oder hexagonal sein. Das Zeichnen mit gdk_draw_pixmap ist einfach genug; Hier ist ein Beispiel dafür, wie es für isometrische Fliesen aussieht:GTK + Ersetze gdk_draw_pixbuf durch Kairo

for(y=0,row=0; y+tile_height<height; y+=tile_half_height,++row) 
    for(x=((row&1)? tile_half_width : 0); x+tile_width<width; x+=tile_width) 
    gdk_draw_pixbuf(widget->window,NULL, 
        pixbuf,src_x,src_y, 
        x,y,tile_width,tile_height, 
        GDK_RGB_DITHER_NONE,0,0); 

Ergebnis:

Isometric tiling with gdk_draw_pixbuf

jedoch zeichnet das gleiche mit Kairo erwiesen sich als recht nicht das gleiche sein. Das ist, was ich bisher habe, was nicht funktioniert:

cairo_t *cr = gdk_cairo_create(widget->window); 
gdk_cairo_set_source_pixbuf(cr,pixbuf,src_x,src_y); 
for(y=0,row=0; y+tile_height<height; y+=tile_half_height,++row) 
    for(x=((row&1)? tile_half_width : 0); x+tile_width<width; x+=tile_width) { 
    cairo_rectangle(cr,x,y,tile_width,tile_height); 
    cairo_paint(cr); 
    } 
} 
cairo_destroy(cr); 

Ergebnis:

Isometric tiling with Cairo

Kairo einfach weigert sich, das Bild zu zeichnen, wie ein normales Rasterbild gezeichnet werden würde. Was mache ich falsch, wie ist das gelöst?

+2

['cairo_paint()' füllt die Clip-Region, nicht den aktuellen Pfad] (https://developer.gnome.org/cairo/stable/cairo-cairo-t.html#cairo-paint); Sie müssen den Pfad, den Sie mit 'cairo_rectangle()' erstellt haben, in einen Clipbereich mit 'cairo_clip()' konvertieren. (Denken Sie daran, dass die Clip-Region im Laufe der Zeit erhalten bleibt. Sie brauchen also 'cairo_save()' und 'cairo_restore()' in Ihrer for-Schleife.) – andlabs

+1

Ich weiß nicht, wie 'cairo_fill' Bildquellen behandelt; Du könntest das versuchen. Ich habe es nur mit festen Farben verwendet. – oldtechaa

+0

Nein, dasselbe Ergebnis. Das Problem ist, dass das gesamte Quellbild als Muster verwendet wird, auch wenn ich nur einen Teil davon verwenden möchte. Ich muss src_x, src_y reparieren, was nicht in Kairo passiert - src_x, src_y ist einfach der Startpunkt im Quellbild, dann passt es sich im Quellbild entsprechend um x, y an. –

Antwort

1

Nicht getestet, könnte aber funktionieren. Wenn nicht, dann berichten, und ich werde versuchen Sie es erneut:

static void _cairo_gdk_draw_pixbuf(cairo_t *cr, cairo_surface_t *source, 
     int src_x, int src_y, 
     int dest_x, int dest_y, 
     int width, int height) 
{ 
    cairo_save(cr); 

    /* Move (0, 0) to the destination position */ 
    cairo_translate(cr, dest_x, dest_y); 

    /* Set up the source surface in such a way that (src_x, src_y) maps to 
    * (0, 0) in user coordinates. */ 
    cairo_set_source_surface(cr, source, -src_x, -src_y); 

    /* Do the drawing */ 
    cairo_rectangle(cr, 0, 0, width, height); 
    cairo_fill(cr); 

    /* Undo all of our modifications to the drawing state */ 
    cairo_restore(cr); 
} 

Die obige Funktion wie gdk_draw_pixbuf funktionieren sollte (na ja, ähnlich).