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>
|
1999-10-28 Jonathan Blandford <jrb@redhat.com>
|
||||||
|
|
||||||
* src/gdk-pixbuf.h: turned convenience macros into convenience
|
* src/gdk-pixbuf.h: turned convenience macros into convenience
|
||||||
|
|||||||
@ -97,7 +97,15 @@ void gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, GdkBitmap *bitmap,
|
|||||||
int width, int height,
|
int width, int height,
|
||||||
int alpha_threshold);
|
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,
|
||||||
|
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 src_x, int src_y,
|
||||||
int dest_x, int dest_y,
|
int dest_x, int dest_y,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
|
|||||||
@ -40,8 +40,9 @@
|
|||||||
* @alpha_threshold: Opacity values below this will be painted as zero; all
|
* @alpha_threshold: Opacity values below this will be painted as zero; all
|
||||||
* other values will be painted as one.
|
* other values will be painted as one.
|
||||||
*
|
*
|
||||||
* Takes the opacity values in a pixbuf and thresholds them to produce a
|
* Takes the opacity values in a rectangular portion of a pixbuf and thresholds
|
||||||
* bi-level alpha mask that can be used as a clipping mask for a drawable.
|
* them to produce a bi-level alpha mask that can be used as a clipping mask for
|
||||||
|
* a drawable.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, GdkBitmap *bitmap,
|
gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, GdkBitmap *bitmap,
|
||||||
@ -119,8 +120,136 @@ gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, GdkBitmap *bitmap,
|
|||||||
gdk_gc_unref (gc);
|
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
|
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,
|
||||||
|
GdkRgbDither dither,
|
||||||
|
int x_dither, int y_dither)
|
||||||
|
{
|
||||||
|
ArtPixBuf *apb;
|
||||||
|
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 src_x, int src_y,
|
||||||
int dest_x, int dest_y,
|
int dest_x, int dest_y,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
@ -130,11 +259,8 @@ gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf, GdkDrawable *drawable,
|
|||||||
int x_dither, int y_dither)
|
int x_dither, int y_dither)
|
||||||
{
|
{
|
||||||
ArtPixBuf *apb;
|
ArtPixBuf *apb;
|
||||||
ArtIRect dest_rect, req_rect, area_rect;
|
|
||||||
GdkBitmap *bitmap;
|
GdkBitmap *bitmap;
|
||||||
GdkGC *gc;
|
GdkGC *gc;
|
||||||
guchar *buf;
|
|
||||||
int rowstride;
|
|
||||||
|
|
||||||
g_return_if_fail (pixbuf != NULL);
|
g_return_if_fail (pixbuf != NULL);
|
||||||
apb = pixbuf->art_pixbuf;
|
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_mask (gc, bitmap);
|
||||||
gdk_gc_set_clip_origin (gc, dest_x, dest_y);
|
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
|
gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc,
|
||||||
* have to pack the buffer first.
|
src_x, src_y,
|
||||||
*/
|
dest_x, dest_y,
|
||||||
if (apb->has_alpha) {
|
width, height,
|
||||||
// buf = remove_alpha (apb, src_x, src_y, width, height, &rowstride);
|
dither,
|
||||||
} else {
|
x_dither, y_dither);
|
||||||
buf = apb->pixels + src_y * apb->rowstride + src_x * 3;
|
|
||||||
rowstride = apb->rowstride;
|
gdk_gc_unref (gc);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user