diff --git a/gdk-pixbuf/gdk-pixbuf-drawable.h b/gdk-pixbuf/gdk-pixbuf-drawable.h new file mode 100644 index 0000000000..08f9222860 --- /dev/null +++ b/gdk-pixbuf/gdk-pixbuf-drawable.h @@ -0,0 +1,12 @@ +#ifndef _GDK_PIXBUF_DRAWABLE_H_ +#define _GDK_PIXBUF_DRAWABLE_H_ +#include +#include + +ArtPixBuf *art_pixbuf_rgb_from_drawable (GdkWindow *window, + gint x, gint y, + gint width, gint height); +ArtPixBuf *art_pixbuf_rgba_from_drawable (GdkWindow *window, + gint x, gint y, + gint width, gint height) +#endif diff --git a/gdk/gdkpixbuf-drawable.c b/gdk/gdkpixbuf-drawable.c new file mode 100644 index 0000000000..472424a5b2 --- /dev/null +++ b/gdk/gdkpixbuf-drawable.c @@ -0,0 +1,135 @@ +/* + * creates an ArtPixBuf from a Drawable + * + * Author: + * Cody Russell + */ +#include +#include +#include +#include +#include +#include "gdk-pixbuf.h" + +/* private function */ + +static ArtPixBuf * +art_pixbuf_from_drawable_core (GdkWindow *window, + gint x, gint y, + gint width, gint height, + gint with_alpha) +{ + GdkImage *image; + ArtPixBuf *pixbuf; + GdkColormap *colormap; + art_u8 *buff; + art_u8 *pixels; + gulong pixel; + gint rowstride; + art_u8 r, g, b; + gint xx, yy; + gint fatness; + + g_return_val_if_fail (window != NULL, NULL); + + image = gdk_image_get (window, x, y, width, height); + colormap = gdk_rgb_get_cmap (); + + fatness = with_alpha ? 4 : 3; + rowstride = width * fatness; + + buff = art_alloc (rowstride * height); + pixels = buff; + + switch (image->depth) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + for (yy = 0; yy < height; yy++) + { + for (xx = 0; xx < width; xx++) + { + pixel = gdk_image_get_pixel (image, xx, yy); + pixels[0] = colormap->colors[pixel].red; + pixels[1] = colormap->colors[pixel].green; + pixels[2] = colormap->colors[pixel].blue; + if (with_alpha) + pixels[3] = 0; + pixels += fatness; + + } + } + break; + + case 16: + case 15: + for (yy = 0; yy < height; yy++) + { + for (xx = 0; xx < width; xx++) + { + pixel = gdk_image_get_pixel (image, xx, yy); + r = (pixel >> 8) & 0xf8; + g = (pixel >> 3) & 0xfc; + b = (pixel << 3) & 0xf8; + pixels[0] = r; + pixels[1] = g; + pixels[2] = b; + if (with_alpha) + pixels[3] = 0; /* GdkImages don't have alpha =) */ + pixels += fatness; + } + } + break; + + case 24: + case 32: + for (yy = 0; yy < height; yy++) + { + for (xx = 0; xx < width; xx++) + { + pixel = gdk_image_get_pixel (image, xx, yy); + r = (pixel >> 16) & 0xff; + g = (pixel >> 8) & 0xff; + b = pixel & 0xff; + pixels[0] = r; + pixels[1] = g; + pixels[2] = b; + if (with_alpha) + pixels[3] = 0; /* GdkImages don't have alpha.. */ + pixels += fatness; + } + } + break; + + default: + g_error ("art_pixbuf_from_drawable_core (): Unknown depth."); + } + + return with_alpha ? art_pixbuf_new_rgba (buff, width, height, rowstride) : + art_pixbuf_new_rgb (buff, width, height, rowstride); +} + +/* Public functions */ + +ArtPixBuf * +art_pixbuf_rgb_from_drawable (GdkWindow *window, + gint x, gint y, + gint width, gint height) +{ + return art_pixbuf_from_drawable_core (window, x, y, width, height, 0); +} + +ArtPixBuf * +art_pixbuf_rgba_from_drawable (GdkWindow *window, + gint x, gint y, + gint width, gint height) +{ + return art_pixbuf_from_drawable_core (window, x, y, width, height, 1); +}