Re : Confused about GDKPixBuf/Cairo interaction

2013-02-20 Thread Lucas Levrel
--- 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-02-20 Thread Edscott Wilson
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

2013-02-20 Thread Colomban Wendling
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

2013-02-18 Thread Rena
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

2013-02-18 Thread Colomban Wendling
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

2013-02-18 Thread Colomban Wendling
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