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);
|
||||
|
||||
@ -39,9 +39,10 @@
|
||||
* @height: Height of region to threshold.
|
||||
* @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,23 +120,148 @@ 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;
|
||||
|
||||
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 (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;
|
||||
|
||||
@ -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