simple rotation support for gdk-pixbuf
- From: Matthias Clasen <mclasen redhat com>
- To: gtk-devel-list gnome org
- Subject: simple rotation support for gdk-pixbuf
- Date: Sun, 20 Jun 2004 02:55:22 -0400
Since a full transformation api a la
http://mail.gnome.org/archives/gtk-devel-list/2003-February/msg00157.html
will probably have to wait for Cairo, here is what I intend to add to
gdk-pixbuf in the 2.6 timeframe:
typedef enum {
GDK_PIXBUF_ANGLE_0 = 0,
GDK_PIXBUF_ANGLE_90 = 90,
GDK_PIXBUF_ANGLE_180 = 180,
GDK_PIXBUF_ANGLE_270 = 270
} GdkPixbufAngle;
GdkPixbuf *gdk_pixbuf_rotate_simple (const GdkPixbuf *src,
GdkPixbufAngle angle);
GdkPixbuf *gdk_pixbuf_flip (const GdkPixbuf *src,
gboolean horizontal,
gboolean vertical);
Does this look reasonable ? Full implementation attached below.
Matthias
#define OFFSET(pb, x, y) ((x) * (pb)->n_channels + (y) * (pb)->rowstride)
/**
* gdk_pixbuf_rotate_simple:
* @src: a #GdkPixbuf
* @angle: the angle to rotate by
*
* Rotates a pixbuf by a multiple of 90 degrees, and returns the
* result in a new pixbuf.
*
* Returns: a new pixbuf
*
* Since: 2.6
*/
GdkPixbuf *
gdk_pixbuf_rotate_simple (const GdkPixbuf *src,
GdkPixbufAngle angle)
{
GdkPixbuf *dest;
guchar *p, *q;
gint x, y;
if (angle == 0)
return gdk_pixbuf_copy (src);
if (angle == 180)
dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha,
8, src->width, src->height);
else
dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha,
8, src->height, src->width);
if (!dest)
return NULL;
switch (angle % 360)
{
case 90:
for (y = 0; y < src->height; y++)
{
for (x = 0; x < src->width; x++)
{
p = src->pixels + OFFSET (src, x, y);
q = dest->pixels + OFFSET (dest, y, src->width - x - 1);
memcpy (q, p, dest->n_channels);
}
}
break;
case 180:
for (y = 0; y < src->height; y++)
{
for (x = 0; x < src->width; x++)
{
p = src->pixels + OFFSET (src, x, y);
q = dest->pixels + OFFSET (dest, src->width - x - 1, src->height - y - 1);
memcpy (q, p, dest->n_channels);
}
}
break;
case 270:
for (y = 0; y < src->height; y++)
{
for (x = 0; x < src->width; x++)
{
p = src->pixels + OFFSET (src, x, y);
q = dest->pixels + OFFSET (dest, src->height - y - 1, x);
memcpy (q, p, dest->n_channels);
}
}
break;
default:
g_assert_not_reached ();
}
return dest;
}
/**
* gdk_pixbuf_flip:
* @src: a #GdkPixbuf
* @horizontal: %TRUE to flip horizontally
* @vertical: %TRUE to flip vertically
*
* Flips a pixbuf horizontally and/or vertically and returns the
* result in a new pixbuf.
*
* Returns: a new pixbuf.
*
* Since: 2.6
*/
GdkPixbuf *
gdk_pixbuf_flip (const GdkPixbuf *src,
gboolean horizontal,
gboolean vertical)
{
GdkPixbuf *dest;
guchar *p, *q;
gint x, y;
if (!horizontal && !vertical)
return gdk_pixbuf_copy (src);
dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha,
8, src->width, src->height);
if (!dest)
return NULL;
if (!horizontal) /* flip vertical */
{
for (y = 0; y < dest->height; y++)
{
p = src->pixels + OFFSET (src, 0, y);
q = dest->pixels + OFFSET (dest, 0, dest->height - y - 1);
memcpy (q, p, dest->rowstride);
}
}
else if (!vertical) /* flip horizontal */
{
for (y = 0; y < dest->height; y++)
{
for (x = 0; x < dest->width; x++)
{
p = src->pixels + OFFSET (src, x, y);
q = dest->pixels + OFFSET (dest, dest->width - x - 1, y);
memcpy (q, p, dest->n_channels);
}
}
}
else /* flip both */
{
for (y = 0; y < dest->height; y++)
{
for (x = 0; x < dest->width; x++)
{
p = src->pixels + OFFSET (src, x, y);
q = dest->pixels + OFFSET (dest, dest->width - x - 1, dest->height - y - 1);
memcpy (q, p, dest->n_channels);
}
}
}
return dest;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]