gnu_java_awt_peer_gtk_GtkImagePainter.c [plain text]
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkImagePainter.h"
#include <libart_lgpl/art_misc.h>
#include <libart_lgpl/art_rgb_affine.h>
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImagePainter_drawPixels
(JNIEnv *env, jobject obj __attribute__((unused)), jobject gc_obj,
jint bg_red, jint bg_green, jint bg_blue, jint x, jint y, jint width,
jint height, jintArray jpixels, jint offset, jint scansize,
jdoubleArray jaffine)
{
struct graphics *g;
jint *pixels, *elems;
guchar *packed;
int i;
jsize num_pixels;
guchar *j_rgba, *c_rgb;
g = (struct graphics *) NSA_GET_PTR (env, gc_obj);
if (!jpixels)
return;
elems = (*env)->GetIntArrayElements (env, jpixels, NULL);
num_pixels = (*env)->GetArrayLength (env, jpixels);
pixels = malloc (sizeof (jint) * num_pixels);
memcpy (pixels, elems, sizeof (jint) * num_pixels);
(*env)->ReleaseIntArrayElements (env, jpixels, elems, 0);
#ifndef WORDS_BIGENDIAN
for (i = 0; i < num_pixels; i++)
pixels[i] = SWAPU32 ((unsigned)pixels[i]);
#endif
packed = (guchar *) malloc (sizeof (guchar) * 3 * num_pixels);
j_rgba = (guchar *) pixels;
c_rgb = packed;
for (i = 0; i < num_pixels; i++)
{
jint ialpha = *j_rgba++;
switch (ialpha)
{
case 0:
*c_rgb++ = bg_red;
*c_rgb++ = bg_green;
*c_rgb++ = bg_blue;
j_rgba += 3;
break;
case 255:
*c_rgb++ = *j_rgba++;
*c_rgb++ = *j_rgba++;
*c_rgb++ = *j_rgba++;
break;
default:
{
jfloat alpha = ialpha / 255.0;
jfloat comp_alpha = 1.0 - alpha;
*c_rgb++ = *j_rgba++ * alpha + bg_red * comp_alpha;
*c_rgb++ = *j_rgba++ * alpha + bg_green * comp_alpha;
*c_rgb++ = *j_rgba++ * alpha + bg_blue * comp_alpha;
}
break;
}
}
if (jaffine)
{
jdouble *affine;
ArtAlphaGamma *alphagamma = NULL;
art_u8 *dst;
int new_width, new_height;
affine = (*env)->GetDoubleArrayElements (env, jaffine, NULL);
new_width = abs (width * affine[0]);
new_height = abs (height * affine[3]);
dst = (art_u8 *) malloc (sizeof (art_u8) * 3 * (new_width * new_height));
art_rgb_affine (dst,
0, 0,
new_width, new_height,
new_width * 3,
(art_u8 *) packed + offset * 3,
width, height,
scansize * 3,
affine,
ART_FILTER_NEAREST,
alphagamma);
(*env)->ReleaseDoubleArrayElements (env, jaffine, affine, JNI_ABORT);
free (packed);
packed = (guchar *) dst;
width = scansize = new_width;
height = new_height;
offset = 0;
}
gdk_threads_enter ();
if (!g || !GDK_IS_DRAWABLE (g->drawable))
{
gdk_threads_leave ();
return;
}
gdk_draw_rgb_image (g->drawable,
g->gc,
x + g->x_offset,
y + g->y_offset,
width, height, GDK_RGB_DITHER_NORMAL,
packed + offset * 3, scansize * 3);
gdk_threads_leave ();
free (pixels);
free (packed);
}