New function to render a portion of a pixbuf to a drawable. Ignores alpha
1999-10-28 Federico Mena Quintero <federico@redhat.com> * src/gdk-pixbuf-render.c (gdk_pixbuf_render_to_drawable): New function to render a portion of a pixbuf to a drawable. Ignores alpha information and takes in a GC. (gdk_pixbuf_render_to_drawable_alpha): New function to render a portion of a pixbuf to a drawable. It automatically creates a GC and a clipping mask for alpha pixbufs.
This commit is contained in:
		
				
					committed by
					
						
						Arturo Espinosa
					
				
			
			
				
	
			
			
			
						parent
						
							7e96137070
						
					
				
				
					commit
					ece5ac121a
				
			@ -1,3 +1,12 @@
 | 
			
		||||
1999-10-28  Federico Mena Quintero  <federico@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* src/gdk-pixbuf-render.c (gdk_pixbuf_render_to_drawable): New
 | 
			
		||||
	function to render a portion of a pixbuf to a drawable.  Ignores
 | 
			
		||||
	alpha information and takes in a GC.
 | 
			
		||||
	(gdk_pixbuf_render_to_drawable_alpha): New function to render a
 | 
			
		||||
	portion of a pixbuf to a drawable.  It automatically creates a GC
 | 
			
		||||
	and a clipping mask for alpha pixbufs.
 | 
			
		||||
 | 
			
		||||
1999-10-28  Jonathan Blandford  <jrb@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* src/gdk-pixbuf.h: turned convenience macros into convenience
 | 
			
		||||
 | 
			
		||||
@ -97,15 +97,23 @@ void gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, GdkBitmap *bitmap,
 | 
			
		||||
					int width, int height,
 | 
			
		||||
					int alpha_threshold);
 | 
			
		||||
 | 
			
		||||
void gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf, GdkDrawable *drawable,
 | 
			
		||||
void gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf,
 | 
			
		||||
				    GdkDrawable *drawable, GdkGC *gc,
 | 
			
		||||
				    int src_x, int src_y,
 | 
			
		||||
				    int dest_x, int dest_y,
 | 
			
		||||
				    int width, int height,
 | 
			
		||||
				    GdkPixbufAlphaMode alpha_mode,
 | 
			
		||||
				    int alpha_threshold,
 | 
			
		||||
				    GdkRgbDither dither,
 | 
			
		||||
				    int x_dither, int y_dither);
 | 
			
		||||
 | 
			
		||||
void gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf, GdkDrawable *drawable,
 | 
			
		||||
					  int src_x, int src_y,
 | 
			
		||||
					  int dest_x, int dest_y,
 | 
			
		||||
					  int width, int height,
 | 
			
		||||
					  GdkPixbufAlphaMode alpha_mode,
 | 
			
		||||
					  int alpha_threshold,
 | 
			
		||||
					  GdkRgbDither dither,
 | 
			
		||||
					  int x_dither, int y_dither);
 | 
			
		||||
 | 
			
		||||
/* Transformations */
 | 
			
		||||
#if 0
 | 
			
		||||
GdkPixbuf *gdk_pixbuf_scale (const GdkPixbuf *pixbuf, gint w, gint h);
 | 
			
		||||
 | 
			
		||||
@ -40,8 +40,9 @@
 | 
			
		||||
 * @alpha_threshold: Opacity values below this will be painted as zero; all
 | 
			
		||||
 * other values will be painted as one.
 | 
			
		||||
 *
 | 
			
		||||
 * Takes the opacity values in a pixbuf and thresholds them to produce a
 | 
			
		||||
 * bi-level alpha mask that can be used as a clipping mask for a drawable.
 | 
			
		||||
 * Takes the opacity values in a rectangular portion of a pixbuf and thresholds
 | 
			
		||||
 * them to produce a bi-level alpha mask that can be used as a clipping mask for
 | 
			
		||||
 * a drawable.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, GdkBitmap *bitmap,
 | 
			
		||||
@ -119,20 +120,71 @@ gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, GdkBitmap *bitmap,
 | 
			
		||||
	gdk_gc_unref (gc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Creates a buffer by stripping the alpha channel of a pixbuf */
 | 
			
		||||
static guchar *
 | 
			
		||||
remove_alpha (ArtPixBuf *apb, int x, int y, int width, int height, int *rowstride)
 | 
			
		||||
{
 | 
			
		||||
	guchar *buf;
 | 
			
		||||
	int xx, yy;
 | 
			
		||||
	guchar *src, *dest;
 | 
			
		||||
 | 
			
		||||
	g_assert (apb->n_channels == 4);
 | 
			
		||||
	g_assert (apb->has_alpha);
 | 
			
		||||
	g_assert (x >= 0 && x + width <= apb->width);
 | 
			
		||||
	g_assert (y >= 0 && y + height <= apb->height);
 | 
			
		||||
 | 
			
		||||
	*rowstride = 4 * ((width * 3 + 3) / 4);
 | 
			
		||||
 | 
			
		||||
	buf = g_new (guchar, *rowstride * height);
 | 
			
		||||
 | 
			
		||||
	for (yy = 0; yy < height; yy++) {
 | 
			
		||||
		src = apb->pixels + apb->rowstride * (yy + y) + x * apb->n_channels;
 | 
			
		||||
		dest = buf + *rowstride * yy;
 | 
			
		||||
 | 
			
		||||
		for (xx = 0; xx < width; xx++) {
 | 
			
		||||
			*dest++ = *src++;
 | 
			
		||||
			*dest++ = *src++;
 | 
			
		||||
			*dest++ = *src++;
 | 
			
		||||
			src++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * gdk_pixbuf_render_to_drawable:
 | 
			
		||||
 * @pixbuf: A pixbuf.
 | 
			
		||||
 * @drawable: Destination drawable.
 | 
			
		||||
 * @gc: GC used for rendering.
 | 
			
		||||
 * @src_x: Source X coordinate within pixbuf.
 | 
			
		||||
 * @src_y: Source Y coordinate within pixbuf.
 | 
			
		||||
 * @dest_x: Destination X coordinate within drawable.
 | 
			
		||||
 * @dest_y: Destination Y coordinate within drawable.
 | 
			
		||||
 * @width: Width of region to render, in pixels.
 | 
			
		||||
 * @height: Height of region to render, in pixels.
 | 
			
		||||
 * @dither: Dithering mode for GdkRGB.
 | 
			
		||||
 * @x_dither: X offset for dither.
 | 
			
		||||
 * @y_dither: Y offset for dither.
 | 
			
		||||
 * 
 | 
			
		||||
 * Renders a rectangular portion of a pixbuf to a drawable while using the
 | 
			
		||||
 * specified GC.  This is done using GdkRGB, so the specified drawable must have
 | 
			
		||||
 * the GdkRGB visual and colormap.  Note that this function will ignore the
 | 
			
		||||
 * opacity information for images with an alpha channel; the GC must already
 | 
			
		||||
 * have the clipping mask set if you want transparent regions to show through.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf, GdkDrawable *drawable,
 | 
			
		||||
gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf,
 | 
			
		||||
			       GdkDrawable *drawable, GdkGC *gc,
 | 
			
		||||
			       int src_x, int src_y,
 | 
			
		||||
			       int dest_x, int dest_y,
 | 
			
		||||
			       int width, int height,
 | 
			
		||||
			       GdkPixbufAlphaMode alpha_mode,
 | 
			
		||||
			       int alpha_threshold,
 | 
			
		||||
			       GdkRgbDither dither,
 | 
			
		||||
			       int x_dither, int y_dither)
 | 
			
		||||
{
 | 
			
		||||
	ArtPixBuf *apb;
 | 
			
		||||
	ArtIRect dest_rect, req_rect, area_rect;
 | 
			
		||||
	GdkBitmap *bitmap;
 | 
			
		||||
	GdkGC *gc;
 | 
			
		||||
	guchar *buf;
 | 
			
		||||
	int rowstride;
 | 
			
		||||
 | 
			
		||||
@ -143,6 +195,80 @@ gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf, GdkDrawable *drawable,
 | 
			
		||||
	g_return_if_fail (apb->n_channels == 3 || apb->n_channels == 4);
 | 
			
		||||
	g_return_if_fail (apb->bits_per_sample == 8);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (drawable != NULL);
 | 
			
		||||
	g_return_if_fail (gc != NULL);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (src_x >= 0 && src_x + width <= apb->width);
 | 
			
		||||
	g_return_if_fail (src_y >= 0 && src_y + height <= apb->height);
 | 
			
		||||
 | 
			
		||||
	/* This will have to be modified once libart supports other image types.
 | 
			
		||||
	 * Also, GdkRGB does not have gdk_draw_rgb_32_image_dithalign(), so we
 | 
			
		||||
	 * have to pack the buffer first.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	if (apb->has_alpha)
 | 
			
		||||
		buf = remove_alpha (apb, src_x, src_y, width, height, &rowstride);
 | 
			
		||||
	else {
 | 
			
		||||
		buf = apb->pixels + src_y * apb->rowstride + src_x * 3;
 | 
			
		||||
		rowstride = apb->rowstride;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gdk_draw_rgb_image_dithalign (drawable, gc,
 | 
			
		||||
				      dest_x, dest_y,
 | 
			
		||||
				      width, height,
 | 
			
		||||
				      dither,
 | 
			
		||||
				      buf, rowstride,
 | 
			
		||||
				      x_dither, y_dither);
 | 
			
		||||
 | 
			
		||||
	if (apb->has_alpha)
 | 
			
		||||
		g_free (buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * gdk_pixbuf_render_to_drawable_alpha:
 | 
			
		||||
 * @pixbuf: A pixbuf.
 | 
			
		||||
 * @drawable: Destination drawable.
 | 
			
		||||
 * @src_x: Source X coordinate within pixbuf.
 | 
			
		||||
 * @src_y: Source Y coordinates within pixbuf.
 | 
			
		||||
 * @dest_x: Destination X coordinate within drawable.
 | 
			
		||||
 * @dest_y: Destination Y coordinate within drawable.
 | 
			
		||||
 * @width: Width of region to render, in pixels.
 | 
			
		||||
 * @height: Height of region to render, in pixels.
 | 
			
		||||
 * @alpha_mode: If the image does not have opacity information, this is ignored.
 | 
			
		||||
 * Otherwise, specifies how to handle transparency when rendering.
 | 
			
		||||
 * @alpha_threshold: If the image does have opacity information and @alpha_mode
 | 
			
		||||
 * is GDK_PIXBUF_ALPHA_BILEVEL, specifies the threshold value for opacity
 | 
			
		||||
 * values.
 | 
			
		||||
 * @dither: Dithering mode for GdkRGB.
 | 
			
		||||
 * @x_dither: X offset for dither.
 | 
			
		||||
 * @y_dither: Y offset for dither.
 | 
			
		||||
 *
 | 
			
		||||
 * Renders a rectangular portion of a pixbuf to a drawable.  This is done using
 | 
			
		||||
 * GdkRGB, so the specified drawable must have the GdkRGB visual and colormap.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf, GdkDrawable *drawable,
 | 
			
		||||
				     int src_x, int src_y,
 | 
			
		||||
				     int dest_x, int dest_y,
 | 
			
		||||
				     int width, int height,
 | 
			
		||||
				     GdkPixbufAlphaMode alpha_mode,
 | 
			
		||||
				     int alpha_threshold,
 | 
			
		||||
				     GdkRgbDither dither,
 | 
			
		||||
				     int x_dither, int y_dither)
 | 
			
		||||
{
 | 
			
		||||
	ArtPixBuf *apb;
 | 
			
		||||
	GdkBitmap *bitmap;
 | 
			
		||||
	GdkGC *gc;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (pixbuf != NULL);
 | 
			
		||||
	apb = pixbuf->art_pixbuf;
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (apb->format == ART_PIX_RGB);
 | 
			
		||||
	g_return_if_fail (apb->n_channels == 3 || apb->n_channels == 4);
 | 
			
		||||
	g_return_if_fail (apb->bits_per_sample == 8);
 | 
			
		||||
 | 
			
		||||
	g_return_if_fail (drawable != NULL);
 | 
			
		||||
	g_return_if_fail (src_x >= 0 && src_x + width <= apb->width);
 | 
			
		||||
	g_return_if_fail (src_y >= 0 && src_y + height <= apb->height);
 | 
			
		||||
@ -163,15 +289,15 @@ gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf, GdkDrawable *drawable,
 | 
			
		||||
 | 
			
		||||
		gdk_gc_set_clip_mask (gc, bitmap);
 | 
			
		||||
		gdk_gc_set_clip_origin (gc, dest_x, dest_y);
 | 
			
		||||
		gdk_bitmap_unref (bitmap);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Sigh, GdkRGB does not have gdk_draw_rgb_32_image_dithalign(), so we
 | 
			
		||||
	 * have to pack the buffer first.
 | 
			
		||||
	 */
 | 
			
		||||
	if (apb->has_alpha) {
 | 
			
		||||
//		buf = remove_alpha (apb, src_x, src_y, width, height, &rowstride);
 | 
			
		||||
	} else {
 | 
			
		||||
		buf = apb->pixels + src_y * apb->rowstride + src_x * 3;
 | 
			
		||||
		rowstride = apb->rowstride;
 | 
			
		||||
	}
 | 
			
		||||
	gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc,
 | 
			
		||||
				       src_x, src_y,
 | 
			
		||||
				       dest_x, dest_y,
 | 
			
		||||
				       width, height,
 | 
			
		||||
				       dither,
 | 
			
		||||
				       x_dither, y_dither);
 | 
			
		||||
 | 
			
		||||
	gdk_gc_unref (gc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user