Re : Confused about GDKPixBuf/Cairo interaction
--- En date de : Lun 18.2.13, Rena hyperhac...@gmail.com a écrit : Recently I've been developing a Game Boy emulator that uses GtkDrawingArea and GdkPixbuf to display the game screen. In addition to the game output I want to also be able to draw text and shapes on the display window, and Cairo seems to be the ideal way to draw shapes. I'm already using Cairo to copy the Pixbuf to the GtkDrawingArea, so that seems like a good sign that Cairo and GdkPixbuf should interact nicely. Hi, Not sure if this can help, but here's what I do. It uses GdkPixmap. double new_x,new_y; new_x=d_area-allocation.width; new_y=d_area-allocation.height; copy_gc=d_area-style-fg_gc[GTK_WIDGET_STATE (d_area)]; pixmap=gdk_pixmap_new(d_area-window,new_x,new_y,-1); cairo=gdk_cairo_create(pixmap); and then, on expose events: gdk_draw_drawable(d_area-window, copy_gc, pixmap, event-area.x, event-area.y, event-area.x, event-area.y, event-area.width, event-area.height); I also have to handle configure events (where the drawing area changes size). -- LL ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Confused about GDKPixBuf/Cairo interaction
2013/2/18 Colomban Wendling lists@herbesfolles.org Or maybe I got you wrong and you'd like to *draw* on your GdkPixbuf? I'm afraid this just isn't possible directly. If you really want to do that, you'll probably have to manually do some pixel conversion. You can create a Cairo surface of the pixbuf's size, draw on that, and then get the surface's pixels which you'd convert manually to the pixbuf format, and push those pixels to the pixbuf. But again, why would you need to draw specifically on a GdkPixbuf? Or you could just use Tadej Borovsak's code: http://www.gtkforums.com/viewtopic.php?t=5204 regards! ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Confused about GDKPixBuf/Cairo interaction
Le 19/02/2013 01:45, Rena a écrit : On Mon, Feb 18, 2013 at 9:24 AM, Colomban Wendling [...] Well, my emulator gets the pixel data from gdk_pixbuf_get_pixels() and writes into that buffer directly; that way it doesn't have to know anything about GDK and can draw pixels by just writing directly into memory, which saves a lot of overhead when it's rendering roughly 1.5 million pixels per second. The emulator also supports Lua extensions which give scripts an object wrapping the pixbuf and lets them draw on it. OK I see. If I use Cairo to draw shapes in the ::draw handler, that means I'd be painting the pixbuf to the GtkDrawingArea's surface, then drawing those shapes onto it? So the actual pixbuf contents wouldn't be modified. Yes. That could lead to complications if a script wants to e.g. produce a screenshot or read pixels back from the pixbuf, as it wouldn't see anything it had drawn itself. Indeed, nothing would be on the pixbuf but the original image. I guess at best I'd need to keep a separate surface around for scripts to draw on, and paint both of those onto the GtkDrawingArea. I guess that's 1 of 4 possibilities: *) use Cairo directly, e.g. instead of creating a buffer compatible with GdkPicbuf (or actually the GdkPixbuf buffer), create your own buffer that uses a Cairo-compatible format and just write to that. Then, you'd just have to create a CairoImageSurface for that buffer and could happily write to your buffer with Cairo. That's probably the faster solution. Note that apparently Cairo don't have any 3-bytes format, even RGB24 has a 4th unused byte. *) convert (manually) data back and forth to and from Cairo (Edscott Wilson pointed you a code doing this). This has the overhead of 2 conversions each time you want to draw on the pixbuf (not counting the conversion performed by GDK in the ::draw handler). *) implement a Cairo surface that can draw directly to the pixbuf (e.g. that does whatever conversion when performing drawings). I don't know how to do that but I guess it's feasible since Cairo already provides various kinds of surfaces (and have a GObject layer). *) handle 2 layers, the pixbuf and what's drawn on. It may show som use case (e.g. one could take a shot with or without additions) but probably only makes things more complex. Mainly I'm just confused at how GDK is using Cairo to do its painting, but they use two different pixel formats. I'm not 100% sure, but I guess they use the specific Cairo surfaces for their targets (e.g. XLib surfaces on X11, Win32 surfaces on Win32 and Quartz surfaces on OSX). And when drawing pixbuf, they convert it (using gdk_cairo_set_source_pixbuf()). ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Confused about GDKPixBuf/Cairo interaction
Hi, just joined the mailing list, been using GTK and related projects for a while now. Recently I've been developing a Game Boy emulator that uses GtkDrawingArea and GdkPixbuf to display the game screen. In addition to the game output I want to also be able to draw text and shapes on the display window, and Cairo seems to be the ideal way to draw shapes. I'm already using Cairo to copy the Pixbuf to the GtkDrawingArea, so that seems like a good sign that Cairo and GdkPixbuf should interact nicely. However, it doesn't look like they should be able to interact at all, as they don't seem to be able to agree on a pixel format: http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new-from-data Currently only RGB images with 8 bits per sample are supported. http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-The-GdkPixbuf-Structure.html#image-data p[0] = red; p[1] = green; p[2] = blue; p[3] = alpha; That seems to suggest that GdkPixbuf supports only RGB (24-bit) and RGBA (32-bit). But... http://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t CAIRO_FORMAT_ARGB32 is ARGB (each pixel is a 32-bit quantity, with alpha in the upper 8 bits...). CAIRO_FORMAT_RGB24 is xRGB (each pixel is a 32-bit quantity, with the upper 8 bits unused...). Neither of those are RGB or RGBA. So, how can Cairo operate on a surface provided by GdkPixbuf? -- Sent from my Game Boy. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Confused about GDKPixBuf/Cairo interaction
Hi, Le 18/02/2013 11:10, Rena a écrit : Hi, just joined the mailing list, been using GTK and related projects for a while now. Recently I've been developing a Game Boy emulator that uses GtkDrawingArea and GdkPixbuf to display the game screen. In addition to the game output I want to also be able to draw text and shapes on the display window, and Cairo seems to be the ideal way to draw shapes. I'm already using Cairo to copy the Pixbuf to the GtkDrawingArea, so that seems like a good sign that Cairo and GdkPixbuf should interact nicely. However, it doesn't look like they should be able to interact at all, as they don't seem to be able to agree on a pixel format: http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-Image-Data-in-Memory.html#gdk-pixbuf-new-from-data Currently only RGB images with 8 bits per sample are supported. http://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-The-GdkPixbuf-Structure.html#image-data p[0] = red; p[1] = green; p[2] = blue; p[3] = alpha; That seems to suggest that GdkPixbuf supports only RGB (24-bit) and RGBA (32-bit). But... http://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t CAIRO_FORMAT_ARGB32 is ARGB (each pixel is a 32-bit quantity, with alpha in the upper 8 bits...). CAIRO_FORMAT_RGB24 is xRGB (each pixel is a 32-bit quantity, with the upper 8 bits unused...). Neither of those are RGB or RGBA. So, how can Cairo operate on a surface provided by GdkPixbuf? I don't really get it. You say you already use Cairo to draw your pixbuf, but also that you can't see how to use a GdkPixbuf with Cairo? This seems contradictory to me. Anyway, what you want is gdk_cairo_set_source_pixbuf()[1] that does the appropriate conversions to create a Cairo pattern from a GdkPixbuf. Then you can use this pattern like any other Cairo pattern (e.g. cairo_paint()), and you're done. Hope it helps. Colomban [1] http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Confused about GDKPixBuf/Cairo interaction
Le 18/02/2013 14:50, Rena a écrit : On Mon, Feb 18, 2013 at 8:35 AM, Colomban Wendling lists@herbesfolles.org wrote: Hi, Le 18/02/2013 11:10, Rena a écrit : Hi, just joined the mailing list, been using GTK and related projects for a while now. Recently I've been developing a Game Boy emulator that uses GtkDrawingArea and GdkPixbuf to display the game screen. In addition to the game output I want to also be able to draw text and shapes on the display window, and Cairo seems to be the ideal way to draw shapes. I'm already using Cairo to copy the Pixbuf to the GtkDrawingArea, so that seems like a good sign that Cairo and GdkPixbuf should interact nicely. [...] I don't really get it. You say you already use Cairo to draw your pixbuf, but also that you can't see how to use a GdkPixbuf with Cairo? This seems contradictory to me. Anyway, what you want is gdk_cairo_set_source_pixbuf()[1] that does the appropriate conversions to create a Cairo pattern from a GdkPixbuf. Then you can use this pattern like any other Cairo pattern (e.g. cairo_paint()), and you're done. Well, in the GtkDrawingArea::draw signal, I receive a cairo_t* that Gdk has created for me, and draw my pixbuf to it: gboolean draw_callback(GtkWidget *widget, cairo_t *cairo) { gdk_cairo_set_source_pixbuf(cairo, pixbuf, 0, 0); cairo_paint(cairo); } but if I want to draw a shape on the pixbuf, I would need to create a cairo_t* of my own for that purpose, and I don't see how to create one that's compatible with the pixel format GdkPixbuf uses. i.e. I want the destination to be my pixbuf, not the source. First, you could very well draw directly on the Cairo context straight in the ::draw handler, give then you don't need caching for decent performances. E.g., just continue drawing stuff in the ::draw handler after you painted the pixbuf. But if you want to draw everything on your own surface and then paint that surface in the ::draw handler, just create a surface with whatever format you need, gdk_cairo_set_source_pixbuf() should be able to do the conversion. The other solution is to use cairo_surface_create_similar(), but this requires a surface to be similar to -- but there is no much reason for that other surface to have a format better suitable to your pixbuf. The Cairo context passed to the ::draw handler is appropriate to draw on the screen, not particularly to draw your pixbuf. But you can very well do this: def prepare_suraface(pix): # use whatever format you need, e.g. ARGB32 or RGB24 surface = Cairo.Surface(cairo.Format.ARGB32, pix.width, pix.height) cr = Cairo.Context(surface) Gdk.cairo_set_source_pixbuf(cr, pix, 0, 0) cr.pain() # and continue drawing stuff cr.move_to(0, 0) cr.line_to(pix.width, pix.height) cr.stroke() return surface and then your simply paint the created surface in your ::draw handler. Of course, doing this is only useful if you need caching the drawn surface, otherwise it'd be faster do directly perform the draws on the ::draw handler. Or maybe I got you wrong and you'd like to *draw* on your GdkPixbuf? I'm afraid this just isn't possible directly. If you really want to do that, you'll probably have to manually do some pixel conversion. You can create a Cairo surface of the pixbuf's size, draw on that, and then get the surface's pixels which you'd convert manually to the pixbuf format, and push those pixels to the pixbuf. But again, why would you need to draw specifically on a GdkPixbuf? Regards, Colomban ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list