diff --git a/docs/reference/gdk-pixbuf/Makefile.am b/docs/reference/gdk-pixbuf/Makefile.am index d88d1faa6c..6879618c9d 100644 --- a/docs/reference/gdk-pixbuf/Makefile.am +++ b/docs/reference/gdk-pixbuf/Makefile.am @@ -19,6 +19,7 @@ TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) tmpl_sources = \ tmpl/creating.sgml \ tmpl/file-loading.sgml \ + tmpl/from-drawables.sgml \ tmpl/gdk-pixbuf-loader.sgml \ tmpl/gdk-pixbuf-unused.sgml \ tmpl/gdk-pixbuf.sgml \ diff --git a/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt b/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt index dfa9355116..9bf5b214c0 100644 --- a/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt +++ b/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt @@ -40,6 +40,11 @@ gdk_pixbuf_render_to_drawable gdk_pixbuf_render_threshold_alpha +
+from-drawables +gdk_pixbuf_get_from_drawable +
+
util gdk_pixbuf_add_alpha diff --git a/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml b/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml index 0687cbb431..b3e8b2cab1 100644 --- a/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml +++ b/docs/reference/gdk-pixbuf/gdk-pixbuf.sgml @@ -4,6 +4,7 @@ + @@ -47,6 +48,7 @@ &gdk-pixbuf-file-loading; &gdk-pixbuf-creating; &gdk-pixbuf-rendering; + &gdk-pixbuf-from-drawables; &gdk-pixbuf-util; &GnomeCanvasPixbuf; &GdkPixbufLoader; diff --git a/docs/reference/gdk-pixbuf/tmpl/from-drawables.sgml b/docs/reference/gdk-pixbuf/tmpl/from-drawables.sgml new file mode 100644 index 0000000000..e8efb59d97 --- /dev/null +++ b/docs/reference/gdk-pixbuf/tmpl/from-drawables.sgml @@ -0,0 +1,45 @@ + +Drawables to Pixbufs + + +Getting parts of a drawable's image data into a pixbuf. + + + + The functions in this section allow you to take the image data + from a GDK drawable and dump it into a #GdkPixbuf. This can be + used for screenshots and other special effects. Note that these + operations can be expensive, since the image data has to be + transferred from the X server to the client program and converted. + + + + + + #GdkPixbuf, gdk_image_get() + + + + + + + + +@dest: +@src: +@cmap: +@src_x: +@src_y: +@dest_x: +@dest_y: +@width: +@height: +@Returns: + + + diff --git a/docs/reference/gdk-pixbuf/tmpl/rendering.sgml b/docs/reference/gdk-pixbuf/tmpl/rendering.sgml index f6b6d9eb47..9eb3562dd8 100644 --- a/docs/reference/gdk-pixbuf/tmpl/rendering.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/rendering.sgml @@ -2,7 +2,7 @@ Rendering -Rendering a Pixbuf to a GDK Drawable. +Rendering a pixbuf to a GDK drawable. @@ -96,8 +96,7 @@ In the future it will do full alpha compositing. @dest_y: @width: @height: -@alpha_threshold: - +@alpha_threshold: + + diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index 61d54dc420..bfe8c63e15 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,3 +1,25 @@ +1999-12-08 Federico Mena Quintero + + * gdk-pixbuf/gdk-pixbuf-drawable.c: Fix includes. + (gdk_pixbuf_get_from_drawable): Implemented the zillion sanity + checks and API definition. The body needs filling in and it needs + to do the Right Thing(tm) for pixmaps plus the given colormap and + windows and their own colormaps. + + * gdk-pixbuf/gdk-pixbuf.h: Added prototype for + gdk_pixbuf_get_from_drawable(). Killed gdk-pixbuf-drawable.h. + + * gdk-pixbuf/Makefile.am: Re-added the gdk-pixbuf-drawable sources. + + * doc/tmpl/from-drawables.sgml: Populated. + + * doc/gdk-pixbuf.sgml: Added the from-drawables section. + + * doc/Makefile.am (tmpl_sources): Added tmpl/from-drawables.sgml. + + * doc/gdk-pixbuf-sections.txt: Added a section for getting pixbufs + from drawables. + 1999-12-07 Federico Mena Quintero * doc/tmpl/gnome-canvas-pixbuf.sgml: Added clarification about @@ -31,24 +53,24 @@ 1999-12-05 Jaka Mocnik * gdk-pixbuf/Makefile.am: removed GNOME_LIBS from testpixbuf_LDADD. - + 1999-12-05 Arjan van de Ven - - * gdk-pixbuf/io-ico.c: Bug in palet-size + + * gdk-pixbuf/io-ico.c: Bug in palet-size calculation fixed 1999-12-04 Arjan van de Ven * gdk-pixbuf/io-bmp.c: Major cleanup, added support for 32 bpp and 4 bpp (uncompressed) images, fixed 1bpp. - + * gdk-pixbuf/io-ras.c: Minor cleanup, ran through lclint * gdk-pixbuf/io-ico.c: Minor cleanup, fixed 1bpp icons, ran through lclint. * gdk-pixbuf/gdk-pixbuf-io.c: Added detection of .CUR files - (Windows Cursor files). These are identical to .ICO files, + (Windows Cursor files). These are identical to .ICO files, except for the signature and 2 extra fields for the hotspot. 1999-12-03 Federico Mena Quintero @@ -151,7 +173,7 @@ * configure.in: Add AM_CONDITIONAL for inside gnome-libs * src/Makefile.am: conditionalize GnomeCanvasPixbuf - + 1999-11-29 Federico Mena Quintero * src/Makefile.am: Uncomment the GnomeCanvasPixbuf sources. This @@ -236,7 +258,7 @@ * src/gnome-canvas-pixbuf.c (gnome_canvas_pixbuf_bounds): implement the bounds method correctly. - (compute_viewport_affine): compute the affine need to fit the + (compute_viewport_affine): compute the affine need to fit the image within the viewport given by the args. (compute_render_affine): call compute_viewport_affine. @@ -283,7 +305,7 @@ Mon Nov 15 17:18:28 1999 George Lebl files. * src/testpixbuf.c: Added final queued draw when done loading image. - + 1999-11-10 Jonathan Blandford * src/gdk-pixbuf-io.c (gdk_pixbuf_load_module): removed spurious @@ -305,12 +327,12 @@ Mon Nov 15 17:18:28 1999 George Lebl * src/testpixbuf.c: Fixed it to use timeout to read from file for progressive loading. Set TBF_KBPS=n, where n is the number of kilobytes/second to simulate in downloading. n has to be an integer. - + * src/io-jpeg.c: Slight cosmetic cleanup. * src/io-pnm.c: Fixed raw PNM loading bug. Also discovered that ASCII PBM loading has a similar problem and will address tomorrow. - + 1999-11-09 Havoc Pennington * src/Makefile.am (libgdk_pixbuf_la_SOURCES): build the @@ -332,7 +354,7 @@ Mon Nov 15 17:18:28 1999 George Lebl implement later. With these changes all JPEG formats appear to load properly for me. - + 1999-11-08 Jonathan Blandford * src/io-ras.c (image_load_increment): Final patch from Arjan. @@ -343,7 +365,7 @@ Mon Nov 15 17:18:28 1999 George Lebl * src/io-pnm.c image_load (): Fixed so we do not create a separate pixel buffer when reading in image - we reuse the pixel data in the GdkPixbuf structure instead. - + 1999-11-08 Michael Fulbright * src/io-pnm.c pnm_read_ascii_scanline (): Added support for @@ -357,7 +379,7 @@ Mon Nov 15 17:18:28 1999 George Lebl of the width, height, x, and y setting and pixels arguments. 1999-11-05 Jonathan Blandford - + * src/io-ras.c (image_load): third patch. Now it seems to load. * src/gdk-pixbuf-io.c: second patch Arjan van de Ven @@ -402,7 +424,7 @@ Mon Nov 15 17:18:28 1999 George Lebl * src/gdk-pixbuf-render.c (gdk_pixbuf_render_to_drawable): In docs, explain what a dither offset is for. - (gdk_pixbuf_render_to_drawable_alpha): Explain why you would use + (gdk_pixbuf_render_to_drawable_alpha): Explain why you would use this function vs. gdk_pixbuf_render_to_drawable(). 1999-11-04 Havoc Pennington @@ -415,8 +437,8 @@ Mon Nov 15 17:18:28 1999 George Lebl library list. Patch untested in the inside-gnome-libs case, I need to commit - then check out to the gnome-libs I'm using. - + then check out to the gnome-libs I'm using. + 1999-11-04 Michael Fulbright * src/io-jpeg.c (image_begin_load): Add update_func callback. diff --git a/gdk-pixbuf/Makefile.am b/gdk-pixbuf/Makefile.am index 5e628364a3..a75dc6e3ff 100644 --- a/gdk-pixbuf/Makefile.am +++ b/gdk-pixbuf/Makefile.am @@ -41,7 +41,6 @@ libexec_LTLIBRARIES = \ #noinst_PROGRAMS = testpixbuf testpixbuf-drawable noinst_PROGRAMS = testpixbuf - DEPS = libgdk_pixbuf.la INCLUDES = -I$(top_builddir)/gdk-pixbuf $(GLIB_CFLAGS) $(LIBART_CFLAGS) $(GTK_CFLAGS) AM_CPPFLAGS = "-DPIXBUF_LIBDIR=\"$(libexecdir)\"" @@ -50,11 +49,11 @@ LDADDS = libgdk_pixbuf.la $(LIBART_LIBS) $(GLIB_LIBS) $(GTK_LIBS) if INSIDE_GNOME_LIBS testpixbuf_LDADD = $(LDADDS) $(LIBART_LIBS) -lgmodule +#testpixbuf_drawable_LDADD = $(LDADDS) else testpixbuf_LDADD = $(LDADDS) $(LIBART_LIBS) $(GNOME_LIBS) -lgmodule -endif - #testpixbuf_drawable_LDADD = $(LDADDS) $(GNOME_LIBS) +endif GDK_PIXBUF_LIBS = $(LIBART_LIBS) $(GLIB_LIBS) $(GTK_LIBS) @@ -74,14 +73,13 @@ libgdk_pixbufincludedir = $(includedir)/gdk-pixbuf libgdk_pixbuf_la_SOURCES = \ gdk-pixbuf.c \ gdk-pixbuf-data.c \ + gdk-pixbuf-drawable.c \ gdk-pixbuf-io.c \ gdk-pixbuf-loader.c \ gdk-pixbuf-render.c \ gdk-pixbuf-util.c \ $(CANVAS_SOURCEFILES) -# gdk-pixbuf-drawable.c \ - libgdk_pixbuf_la_LDFLAGS = -version-info 1:0:0 libgdk_pixbufinclude_HEADERS = \ @@ -89,8 +87,6 @@ libgdk_pixbufinclude_HEADERS = \ gdk-pixbuf-loader.h \ $(CANVAS_HEADERFILES) -# gdk-pixbuf-drawable.h \ - noinst_HEADERS = \ gdk-pixbuf-io.h diff --git a/gdk-pixbuf/gdk-pixbuf-drawable.h b/gdk-pixbuf/gdk-pixbuf-drawable.h deleted file mode 100644 index 580c29cea9..0000000000 --- a/gdk-pixbuf/gdk-pixbuf-drawable.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _GDK_PIXBUF_DRAWABLE_H_ -#define _GDK_PIXBUF_DRAWABLE_H_ - -#include -#include - -GdkPixbuf *gdk_pixbuf_rgb_from_drawable (GdkWindow *window, gint x, gint y, gint width, gint height); -GdkPixbuf *gdk_pixbuf_rgba_from_drawable (GdkWindow *window, gint x, gint y, gint width, gint height); - -#endif /* _GDK_PIXBUF_DRAWABLE_H_ */ diff --git a/gdk-pixbuf/gdk-pixbuf.h b/gdk-pixbuf/gdk-pixbuf.h index 8712ef477e..920ecf6ed7 100644 --- a/gdk-pixbuf/gdk-pixbuf.h +++ b/gdk-pixbuf/gdk-pixbuf.h @@ -118,6 +118,19 @@ void gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf, GdkDrawable *drawab GdkRgbDither dither, int x_dither, int y_dither); + +#if 0 + +/* Fetching a region from a drawable */ + +GdkPixbuf *gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, + GdkDrawable *src, GdkColormap *cmap, + int src_x, int src_y, + int dest_x, int dest_y, + int width, int height); + +#endif + #ifdef __cplusplus diff --git a/gdk/gdkpixbuf-drawable.c b/gdk/gdkpixbuf-drawable.c index b2af116aef..735e43ada0 100644 --- a/gdk/gdkpixbuf-drawable.c +++ b/gdk/gdkpixbuf-drawable.c @@ -1,28 +1,38 @@ -/* - * Creates an GdkPixbuf from a Drawable +/* GdkPixbuf library - convert X drawable information to RGB * - * Authors: - * Cody Russell - * Michael Zucchi + * Copyright (C) 1999 Michael Zucchi * - * This is licensed software, see the file COPYING for - * details. + * Authors: Michael Zucchi + * Cody Russell + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ #include #include #include -#include -#include #include "gdk-pixbuf.h" -#include "gdk-pixbuf-drawable.h" - #if (G_BYTE_ORDER == G_LITTLE_ENDIAN) #define LITTLE #endif #define d(x) + + static unsigned long mask_table[] = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, @@ -35,11 +45,14 @@ static unsigned long mask_table[] = { 0xffffffff }; + + /* convert 1 bits-pixel data no alpha */ -static void rgb1(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb1 (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -48,7 +61,7 @@ static void rgb1(GdkImage *image, art_u8 *pixels, int rowstride) register unsigned char data; unsigned char *o; unsigned char *srow = image->mem, *orow = pixels; - GdkColormap *colormap; + GdkColormap *colormap; d (printf ("1 bits/pixel\n")); @@ -58,15 +71,15 @@ static void rgb1(GdkImage *image, art_u8 *pixels, int rowstride) width = image->width; height = image->height; bpl = image->bpl; - + colormap = gdk_rgb_get_cmap (); for (yy = 0; yy < height; yy++) { s = srow; o = orow; - + for (xx = 0; xx < width; xx ++) { - data = srow[xx>>3] >> (7 - (xx & 7)) & 1; + data = srow[xx >> 3] >> (7 - (xx & 7)) & 1; *o++ = colormap->colors[data].red; *o++ = colormap->colors[data].green; *o++ = colormap->colors[data].blue; @@ -80,7 +93,8 @@ static void rgb1(GdkImage *image, art_u8 *pixels, int rowstride) convert 1 bits/pixel data with alpha */ -static void rgb1a(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb1a (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -90,7 +104,7 @@ static void rgb1a(GdkImage *image, art_u8 *pixels, int rowstride) unsigned char *o; unsigned char *srow = image->mem, *orow = pixels; unsigned long remap[2]; - GdkColormap *colormap; + GdkColormap *colormap; d (printf ("1 bits/pixel\n")); @@ -100,29 +114,29 @@ static void rgb1a(GdkImage *image, art_u8 *pixels, int rowstride) width = image->width; height = image->height; bpl = image->bpl; - + colormap = gdk_rgb_get_cmap (); - for (xx=0;xx<2;xx++) { + for (xx = 0; xx < 2; xx++) { #ifdef LITTLE remap[xx] = 0xff000000 - | colormap->colors[xx].blue<<16 - | colormap->colors[xx].green<<8 + | colormap->colors[xx].blue << 16 + | colormap->colors[xx].green << 8 | colormap->colors[xx].red; #else remap[xx] = 0xff - | colormap->colors[xx].red<<24 - | colormap->colors[xx].green<<16 - | colormap->colors[xx].red<<8; + | colormap->colors[xx].red << 24 + | colormap->colors[xx].green << 16 + | colormap->colors[xx].red << 8; #endif } for (yy = 0; yy < height; yy++) { s = srow; o = orow; - + for (xx = 0; xx < width; xx ++) { - data = srow[xx>>3] >> (7 - (xx & 7)) & 1; + data = srow[xx >> 3] >> (7 - (xx & 7)) & 1; *o++ = remap[data]; } srow += bpl; @@ -134,7 +148,8 @@ static void rgb1a(GdkImage *image, art_u8 *pixels, int rowstride) convert 8 bits/pixel data no alpha */ -static void rgb8(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb8 (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -144,18 +159,18 @@ static void rgb8(GdkImage *image, art_u8 *pixels, int rowstride) unsigned char *srow = image->mem, *orow = pixels; register unsigned char *s; register unsigned char *o; - GdkColormap *colormap; - + GdkColormap *colormap; + width = image->width; height = image->height; bpl = image->bpl; - d(printf("8 bit, no alpha output\n")); - + d (printf ("8 bit, no alpha output\n")); + colormap = gdk_rgb_get_cmap (); mask = mask_table[image->depth]; - for (yy = 0;yy < height; yy++) { + for (yy = 0; yy < height; yy++) { s = srow; o = orow; for (xx = 0; xx < width; xx++) { @@ -173,7 +188,8 @@ static void rgb8(GdkImage *image, art_u8 *pixels, int rowstride) convert 8 bits/pixel data with alpha */ -static void rgb8a(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb8a (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -181,37 +197,37 @@ static void rgb8a(GdkImage *image, art_u8 *pixels, int rowstride) unsigned long mask; register unsigned long data; GdkColormap *colormap; - unsigned long remap[256]; + unsigned long remap[256]; register unsigned char *s; /* read 2 pixels at once */ register unsigned long *o; unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - d(printf("8 bit, with alpha output\n")); - + d (printf ("8 bit, with alpha output\n")); + colormap = gdk_rgb_get_cmap (); mask = mask_table[image->depth]; - - for (xx=0;xxsize;xx++) { + + for (xx = 0; xx < colormap->size; xx++) { #ifdef LITTLE remap[xx] = 0xff000000 - | colormap->colors[xx].blue<<16 - | colormap->colors[xx].green<<8 + | colormap->colors[xx].blue << 16 + | colormap->colors[xx].green << 8 | colormap->colors[xx].red; #else remap[xx] = 0xff - | colormap->colors[xx].red<<24 - | colormap->colors[xx].green<<16 - | colormap->colors[xx].red<<8; + | colormap->colors[xx].red << 24 + | colormap->colors[xx].green << 16 + | colormap->colors[xx].red << 8; #endif } - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { s = srow; - o = (unsigned long *)orow; + o = (unsigned long *) orow; for (xx = 0; xx < width; xx ++) { data = *s++ & mask; *o++ = remap[data]; @@ -226,12 +242,13 @@ static void rgb8a(GdkImage *image, art_u8 *pixels, int rowstride) no alpha data in lsb format */ -static void rgb565lsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb565lsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; int bpl; - + #ifdef LITTLE register unsigned long *s; /* read 2 pixels at once */ #else @@ -239,18 +256,18 @@ static void rgb565lsb(GdkImage *image, art_u8 *pixels, int rowstride) #endif register unsigned short *o; unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { #ifdef LITTLE - s = (unsigned long *)srow; + s = (unsigned long *) srow; #else - s = (unsigned char *)srow; + s = (unsigned char *) srow; #endif - o = (unsigned short *)orow; + o = (unsigned short *) orow; for (xx = 1; xx < width; xx += 2) { register unsigned long data; #ifdef LITTLE @@ -260,8 +277,8 @@ static void rgb565lsb(GdkImage *image, art_u8 *pixels, int rowstride) *o++ = ((data & 0x7e00000) >> 19) | (data & 0x1f0000) >> 5; #else /* swap endianness first */ - data = s[0] | s[1]<<8 | s[2]<<16 | s[3]<<24; - s+=4; + data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + s += 4; *o++ = (data & 0xf800) | (data & 0x7e0) >> 3; *o++ = (data & 0x1f) << 11 | (data & 0xf8000000) >> 24; *o++ = ((data & 0x7e00000) >> 11) | (data & 0x1f0000) >> 13; @@ -290,12 +307,13 @@ static void rgb565lsb(GdkImage *image, art_u8 *pixels, int rowstride) no alpha data in msb format */ -static void rgb565msb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb565msb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; int bpl; - + #ifdef LITTLE register unsigned char *s; /* need to swap data order */ #else @@ -303,24 +321,24 @@ static void rgb565msb(GdkImage *image, art_u8 *pixels, int rowstride) #endif register unsigned short *o; unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { #ifdef LITTLE s = srow; #else - s = (unsigned long *)srow; + s = (unsigned long *) srow; #endif - o = (unsigned short *)orow; + o = (unsigned short *) orow; for (xx = 1; xx < width; xx += 2) { register unsigned long data; #ifdef LITTLE /* swap endianness first */ - data = s[0] | s[1]<<8 | s[2]<<16 | s[3]<<24; - s+=4; + data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + s += 4; *o++ = (data & 0xf800) >> 8 | (data & 0x7e0) << 5; *o++ = (data & 0x1f) << 3 | (data & 0xf8000000) >> 16; *o++ = ((data & 0x7e00000) >> 19) | (data & 0x1f0000) >> 5; @@ -354,7 +372,8 @@ static void rgb565msb(GdkImage *image, art_u8 *pixels, int rowstride) with alpha data in lsb format */ -static void rgb565alsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb565alsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -366,32 +385,32 @@ static void rgb565alsb(GdkImage *image, art_u8 *pixels, int rowstride) register unsigned char *s; #endif register unsigned long *o; - + unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { #ifdef LITTLE - s = (unsigned short *)srow; + s = (unsigned short *) srow; #else - s = (unsigned char *)srow; + s = (unsigned char *) srow; #endif - o = (unsigned long *)orow; + o = (unsigned long *) orow; for (xx = 0; xx < width; xx ++) { register unsigned long data; /* rrrrrggg gggbbbbb -> rrrrr000 gggggg00 bbbbb000 aaaaaaaa */ /* little endian: aaaaaaaa bbbbb000 gggggg00 rrrrr000 */ #ifdef LITTLE data = *s++; - *o++ = (data & 0xf800) >>8 | (data & 0x7e0) << 5 + *o++ = (data & 0xf800) >> 8 | (data & 0x7e0) << 5 | (data & 0x1f) << 19 | 0xff000000; #else /* swap endianness first */ - data = s[0] | s[1]<<8; - s+=2; + data = s[0] | s[1] << 8; + s += 2; *o++ = (data & 0xf800) << 16 | (data & 0x7e0) << 13 | (data & 0x1f) << 11 | 0xff; #endif @@ -406,7 +425,8 @@ static void rgb565alsb(GdkImage *image, art_u8 *pixels, int rowstride) with alpha data in msb format */ -static void rgb565amsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb565amsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -418,25 +438,25 @@ static void rgb565amsb(GdkImage *image, art_u8 *pixels, int rowstride) register unsigned short *s; /* read 1 pixels at once */ #endif register unsigned long *o; - + unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { s = srow; - o = (unsigned long *)orow; + o = (unsigned long *) orow; for (xx = 0; xx < width; xx ++) { register unsigned long data; /* rrrrrggg gggbbbbb -> rrrrr000 gggggg00 bbbbb000 aaaaaaaa */ /* little endian: aaaaaaaa bbbbb000 gggggg00 rrrrr000 */ #ifdef LITTLE /* swap endianness first */ - data = s[0] | s[1]<<8; - s+=2; - *o++ = (data & 0xf800) >>8 | (data & 0x7e0) << 5 + data = s[0] | s[1] << 8; + s += 2; + *o++ = (data & 0xf800) >> 8 | (data & 0x7e0) << 5 | (data & 0x1f) << 19 | 0xff000000; #else data = *s++; @@ -454,12 +474,13 @@ static void rgb565amsb(GdkImage *image, art_u8 *pixels, int rowstride) no alpha data in lsb format */ -static void rgb555lsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb555lsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; int bpl; - + #ifdef LITTLE register unsigned long *s; /* read 2 pixels at once */ #else @@ -467,18 +488,18 @@ static void rgb555lsb(GdkImage *image, art_u8 *pixels, int rowstride) #endif register unsigned short *o; unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { #ifdef LITTLE - s = (unsigned long *)srow; + s = (unsigned long *) srow; #else s = srow; #endif - o = (unsigned short *)orow; + o = (unsigned short *) orow; for (xx = 1; xx < width; xx += 2) { register unsigned long data; #ifdef LITTLE @@ -488,8 +509,8 @@ static void rgb555lsb(GdkImage *image, art_u8 *pixels, int rowstride) *o++ = ((data & 0x3e00000) >> 18) | (data & 0x1f0000) >> 5; #else /* swap endianness first */ - data = s[0] | s[1]<<8 | s[2]<<16 | s[3]<<24; - s+=4; + data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + s += 4; *o++ = (data & 0x7c00) << 1 | (data & 0x3e0) >> 2; *o++ = (data & 0x1f) << 11 | (data & 0x7c000000) >> 23; *o++ = ((data & 0x3e00000) >> 10) | (data & 0x1f0000) >> 13; @@ -518,12 +539,13 @@ static void rgb555lsb(GdkImage *image, art_u8 *pixels, int rowstride) no alpha data in msb format */ -static void rgb555msb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb555msb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; int bpl; - + #ifdef LITTLE register unsigned char *s; /* read 2 pixels at once */ #else @@ -531,20 +553,20 @@ static void rgb555msb(GdkImage *image, art_u8 *pixels, int rowstride) #endif register unsigned short *o; unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { s = srow; - o = (unsigned short *)orow; + o = (unsigned short *) orow; for (xx = 1; xx < width; xx += 2) { register unsigned long data; #ifdef LITTLE /* swap endianness first */ - data = s[0] | s[1]<<8 | s[2]<<16 | s[3]<<24; - s+=4; + data = s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + s += 4; *o++ = (data & 0x7c00) >> 7 | (data & 0x3e0) << 6; *o++ = (data & 0x1f) << 3 | (data & 0x7c000000) >> 15; *o++ = ((data & 0x3e00000) >> 18) | (data & 0x1f0000) >> 5; @@ -578,7 +600,8 @@ static void rgb555msb(GdkImage *image, art_u8 *pixels, int rowstride) with alpha data in lsb format */ -static void rgb555alsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb555alsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -590,32 +613,32 @@ static void rgb555alsb(GdkImage *image, art_u8 *pixels, int rowstride) register unsigned char *s; #endif register unsigned long *o; - + unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { #ifdef LITTLE - s = (unsigned short *)srow; + s = (unsigned short *) srow; #else s = srow; #endif - o = (unsigned long *)orow; + o = (unsigned long *) orow; for (xx = 0; xx < width; xx++) { register unsigned long data; /* rrrrrggg gggbbbbb -> rrrrr000 gggggg00 bbbbb000 aaaaaaaa */ /* little endian: aaaaaaaa bbbbb000 gggggg00 rrrrr000 */ #ifdef LITTLE data = *s++; - *o++ = (data & 0x7c00) >>7 | (data & 0x3e0) << 6 + *o++ = (data & 0x7c00) >> 7 | (data & 0x3e0) << 6 | (data & 0x1f) << 19 | 0xff000000; #else /* swap endianness first */ - data = s[0] | s[1]<<8; - s+=2; + data = s[0] | s[1] << 8; + s += 2; *o++ = (data & 0x7c00) << 17 | (data & 0x3e0) << 14 | (data & 0x1f) << 11 | 0xff; #endif @@ -630,7 +653,8 @@ static void rgb555alsb(GdkImage *image, art_u8 *pixels, int rowstride) with alpha data in msb format */ -static void rgb555amsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb555amsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -642,28 +666,28 @@ static void rgb555amsb(GdkImage *image, art_u8 *pixels, int rowstride) register unsigned char *s; #endif register unsigned long *o; - + unsigned char *srow = image->mem, *orow = pixels; - + width = image->width; height = image->height; bpl = image->bpl; - - for (yy = 0;yy < height; yy++) { + + for (yy = 0; yy < height; yy++) { #ifdef LITTLE - s = (unsigned short *)srow; + s = (unsigned short *) srow; #else s = srow; #endif - o = (unsigned long *)orow; + o = (unsigned long *) orow; for (xx = 0; xx < width; xx++) { register unsigned long data; /* rrrrrggg gggbbbbb -> rrrrr000 gggggg00 bbbbb000 aaaaaaaa */ /* little endian: aaaaaaaa bbbbb000 gggggg00 rrrrr000 */ #ifdef LITTLE /* swap endianness first */ - data = s[0] | s[1]<<8; - s+=2; + data = s[0] | s[1] << 8; + s += 2; *o++ = (data & 0x7c00) >>7 | (data & 0x3e0) << 6 | (data & 0x1f) << 19 | 0xff000000; #else @@ -678,7 +702,8 @@ static void rgb555amsb(GdkImage *image, art_u8 *pixels, int rowstride) } -static void rgb888alsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb888alsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -691,9 +716,9 @@ static void rgb888alsb(GdkImage *image, art_u8 *pixels, int rowstride) width = image->width; height = image->height; bpl = image->bpl; - - d(printf ("32 bits/pixel with alpha\n")); - + + d (printf ("32 bits/pixel with alpha\n")); + /* lsb data */ for (yy = 0; yy < height; yy++) { s = srow; @@ -710,7 +735,8 @@ static void rgb888alsb(GdkImage *image, art_u8 *pixels, int rowstride) } } -static void rgb888lsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb888lsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -723,7 +749,7 @@ static void rgb888lsb(GdkImage *image, art_u8 *pixels, int rowstride) height = image->height; bpl = image->bpl; - d(printf("32 bit, lsb, no alpha\n")); + d (printf ("32 bit, lsb, no alpha\n")); for (yy = 0; yy < height; yy++) { s = srow; @@ -739,7 +765,8 @@ static void rgb888lsb(GdkImage *image, art_u8 *pixels, int rowstride) } } -static void rgb888amsb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb888amsb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -754,7 +781,7 @@ static void rgb888amsb(GdkImage *image, art_u8 *pixels, int rowstride) unsigned char *o; #endif - d(printf("32 bit, msb, with alpha\n")); + d (printf ("32 bit, msb, with alpha\n")); width = image->width; height = image->height; @@ -763,8 +790,8 @@ static void rgb888amsb(GdkImage *image, art_u8 *pixels, int rowstride) /* msb data */ for (yy = 0; yy < height; yy++) { #ifdef LITTLE - s = (unsigned long *)srow; - o = (unsigned long *)orow; + s = (unsigned long *) srow; + o = (unsigned long *) orow; #else s = srow; o = orow; @@ -777,7 +804,7 @@ static void rgb888amsb(GdkImage *image, art_u8 *pixels, int rowstride) *o++ = 0xff; s += 4; #else - *o++ = (*s <<8 ) | 0xff; /* untested */ + *o++ = (*s << 8) | 0xff; /* untested */ s++; #endif } @@ -786,7 +813,8 @@ static void rgb888amsb(GdkImage *image, art_u8 *pixels, int rowstride) } } -static void rgb888msb(GdkImage *image, art_u8 *pixels, int rowstride) +static void +rgb888msb (GdkImage *image, art_u8 *pixels, int rowstride) { int xx, yy; int width, height; @@ -796,7 +824,7 @@ static void rgb888msb(GdkImage *image, art_u8 *pixels, int rowstride) unsigned char *s; unsigned char *o; - d(printf("32 bit, msb, no alpha\n")); + d (printf ("32 bit, msb, no alpha\n")); width = image->width; height = image->height; @@ -816,7 +844,7 @@ static void rgb888msb(GdkImage *image, art_u8 *pixels, int rowstride) } } -typedef void (*cfunc) (GdkImage *image, art_u8 *pixels, int rowstride); +typedef void (* cfunc) (GdkImage *image, art_u8 *pixels, int rowstride); static cfunc convert_map[] = { rgb1,rgb1,rgb1a,rgb1a, @@ -829,22 +857,37 @@ static cfunc convert_map[] = { /* perform actual conversion */ -static void rgbconvert(GdkImage *image, art_u8 *pixels, int rowstride, int alpha) +static void +rgbconvert (GdkImage *image, art_u8 *pixels, int rowstride, int alpha) { - int index = (image->byte_order == GDK_MSB_FIRST) - | (alpha!=0) << 1; + int index = (image->byte_order == GDK_MSB_FIRST) | (alpha != 0) << 1; int bank=0; switch (image->depth) { - case 1: bank = 0; break; - case 8: bank = 1; break; - case 15: bank = 2; break; - case 16: bank = 3; break; + case 1: + bank = 0; + break; + + case 8: + bank = 1; + break; + + case 15: + bank = 2; + break; + + case 16: + bank = 3; + break; + case 24: - case 32: bank = 4; break; + case 32: + bank = 4; + break; } - index |= bank<<2; - convert_map[index](image, pixels, rowstride); + + index |= bank << 2; + (* convert_map[index]) (image, pixels, rowstride); } static GdkPixbuf * @@ -860,15 +903,15 @@ gdk_pixbuf_from_drawable_core (GdkPixmap * window, gint x, gint y, gint width, gint screen_width, screen_height; gint window_width, window_height, window_x, window_y; int bpl; - + g_return_val_if_fail (window != NULL, NULL); - + /* always returns image in ZPixmap format ... */ image = gdk_image_get (window, x, y, width, height); - + fatness = with_alpha ? 4 : 3; rowstride = width * fatness; - + buff = art_alloc (rowstride * height); pixels = buff; @@ -878,38 +921,153 @@ gdk_pixbuf_from_drawable_core (GdkPixmap * window, gint x, gint y, gint width, printf ("byte order = %d\n", image->byte_order); printf ("bytes/line = %d\n", image->bpl); #endif - + bpl = image->bpl; - - rgbconvert(image, pixels, rowstride, with_alpha); + + rgbconvert (image, pixels, rowstride, with_alpha); gdk_image_destroy (image); - + if (with_alpha) art_pixbuf = art_pixbuf_new_rgba (buff, width, height, rowstride); else art_pixbuf = art_pixbuf_new_rgb (buff, width, height, rowstride); - + return gdk_pixbuf_new_from_art_pixbuf (art_pixbuf); } -/* Public functions */ - -GdkPixbuf * -gdk_pixbuf_rgb_from_drawable (GdkWindow * window, gint x, gint y, gint width, - gint height) -{ - return gdk_pixbuf_from_drawable_core (window, x, y, width, height, 0); -} + -GdkPixbuf * -gdk_pixbuf_rgba_from_drawable (GdkWindow * window, gint x, gint y, gint width, - gint height) -{ - return gdk_pixbuf_from_drawable_core (window, x, y, width, height, 1); -} +/* Exported functions */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ +/** + * gdk_pixbuf_get_from_drawable: + * @dest: Destination pixbuf, or NULL if a new pixbuf should be created. + * @src: Source drawable. + * @cmap: A colormap if @src is a pixmap. If it is a window, this argument will + * be ignored. + * @src_x: Source X coordinate within drawable. + * @src_y: Source Y coordinate within drawable. + * @dest_x: Destination X coordinate in pixbuf, or 0 if @dest is NULL. + * @dest_y: Destination Y coordinate in pixbuf, or 0 if @dest is NULL. + * @width: Width in pixels of region to get. + * @height: Height in pixels of region to get. + * + * Transfers image data from a Gdk drawable and converts it to an RGB(A) + * representation inside a GdkPixbuf. + * + * If the drawable @src is a pixmap, then a suitable colormap must be specified, + * since pixmaps are just blocks of pixel data without an associated colormap. + * If the drawable is a window, the @cmap argument will be ignored and the + * window's own colormap will be used instead. + * + * If the specified destination pixbuf @dest is #NULL, then this function will + * create an RGB pixbuf with 8 bits per channel and no alpha, with the same size + * specified by the @width and @height arguments. In this case, the @dest_x and + * @dest_y arguments must be specified as 0, otherwise the function will return + * #NULL. If the specified destination pixbuf is not NULL and it contains alpha + * information, then the filled pixels will be set to full opacity. + * + * If the specified drawable is a pixmap, then the requested source rectangle + * must be completely contained within the pixmap, otherwise the function will + * return #NULL. + * + * If the specified drawable is a window, then it must be viewable, i.e. all of + * its ancestors up to the root window must be mapped. Also, the specified + * source rectangle must be completely contained within the window and within + * the screen. If regions of the window are obscured by noninferior windows, the + * contents of those regions are undefined. The contents of regions obscured by + * inferior windows of a different depth than that of the source window will also + * be undefined. + * + * Return value: The same pixbuf as @dest if it was non-NULL, or a newly-created + * pixbuf with a reference count of 1 if no destination pixbuf was specified. + **/ +GdkPixbuf * +gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, + GdkDrawable *src, GdkColormap *cmap, + int src_x, int src_y, + int dest_x, int dest_y, + int width, int height) +{ + GdkWindowType window_type; + gint src_width, src_height; + ArtPixBuf *apb; + + /* General sanity checks */ + + g_return_val_if_fail (src != NULL, NULL); + + window_type = gdk_window_get_type (src); + + if (window_type == GDK_WINDOW_PIXMAP) + g_return_val_if_fail (cmap != NULL, NULL); + else + /* FIXME: this is not perfect, since is_viewable() only tests + * recursively up the Gdk parent window tree, but stops at + * foreign windows or Gdk toplevels. I.e. if a window manager + * unmapped one of its own windows, this won't work. + */ + g_return_val_if_fail (gdk_window_is_viewable (src), NULL); + + if (!dest) + g_return_val_if_fail (dest_x == 0 && dest_y == 0, NULL); + else { + apb = dest->art_pixbuf; + + g_return_val_if_fail (apb->format == ART_PIX_RGB, NULL); + g_return_val_if_fail (apb->n_channels == 3 || apb->n_channels == 4, NULL); + g_return_val_if_fail (apb->bits_per_sample == 8, NULL); + } + + /* Coordinate sanity checks */ + + gdk_window_get_size (src, &src_width, &src_height); + + g_return_val_if_fail (src_x >= 0 && src_y >= 0, NULL); + g_return_val_if_fail (src_x + width <= src_width && src_y + height <= src_height, NULL); + + if (dest) { + g_return_val_if_fail (dest_x >= 0 && dest_y >= 0, NULL); + g_return_val_if_fail (dest_x + width <= apb->width, NULL); + g_return_val_if_fail (dest_y + height <= apb->height, NULL); + } + + if (window_type != GDK_WINDOW_PIXMAP) { + int ret; + gint src_xorigin, src_yorigin; + int screen_width, screen_height; + int screen_srcx, screen_srcy; + + ret = gdk_window_get_origin (src, &src_xorigin, &src_yorigin); + g_return_val_if_fail (ret != FALSE, NULL); + + screen_width = gdk_screen_width (); + screen_height = gdk_screen_height (); + + screen_srcx = src_xorigin + src_x; + screen_srcy = src_yorigin + src_y; + + g_return_val_if_fail (screen_srcx >= 0 && screen_srcy >= 0, NULL); + g_return_val_if_fail (screen_srcx + width <= screen_width, NULL); + g_return_val_if_fail (screen_srcy + height <= screen_height, NULL); + } + + /* Create the pixbuf if needed */ + + if (!dest) { + dest = gdk_pixbuf_new (ART_PIX_RGB, FALSE, 8, width, height); + if (!dest) + return NULL; + + apb = dest->art_pixbuf; + } + + /* Get the colormap if needed */ + + if (window_type != GDK_WINDOW_PIXMAP) + cmap = gdk_window_get_colormap (src); + + /* FIXME: fill in the body here */ + + return dest; +}