Index: ChangeLog =================================================================== RCS file: /cvsroot/classpath/classpath/ChangeLog,v retrieving revision 1.2386 diff -u -r1.2386 ChangeLog --- ChangeLog 4 Aug 2004 21:05:51 -0000 1.2386 +++ ChangeLog 6 Aug 2004 00:55:04 -0000 @@ -1,3 +1,11 @@ +2004-08-05 Craig Black + + * gnu/java/awt/peer/gtk/GdkGraphics.java + (drawImage): Add support for scaling pixmaps. + * include/gnu_java_awt_peer_gtk_GdkGraphics.h, + * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c + (copyAndScalePixmap): New native method. + 2004-08-04 Patrik Reali * doc/www.gnu.org/newsitems.txt: latest AWT+SWING screenshots Index: gnu/java/awt/peer/gtk/GdkGraphics.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java,v retrieving revision 1.27 diff -u -r1.27 GdkGraphics.java --- gnu/java/awt/peer/gtk/GdkGraphics.java 30 Jul 2004 16:43:18 -0000 1.27 +++ gnu/java/awt/peer/gtk/GdkGraphics.java 6 Aug 2004 00:55:05 -0000 @@ -126,6 +126,11 @@ native public void dispose (); native void copyPixmap (Graphics g, int x, int y, int width, int height); + native void copyAndScalePixmap (Graphics g, boolean flip_x, boolean flip_y, + int src_x, int src_y, + int src_width, int src_height, + int dest_x, int dest_y, + int dest_width, int dest_height); public boolean drawImage (Image img, int x, int y, Color bgcolor, ImageObserver observer) { @@ -161,7 +166,10 @@ { if (img instanceof GtkOffScreenImage) { - throw new RuntimeException (); + copyAndScalePixmap (img.getGraphics (), false, false, + 0, 0, img.getWidth (null), img.getHeight (null), + x, y, width, height); + return true; } GtkImage image = (GtkImage) img; @@ -186,7 +194,60 @@ { if (img instanceof GtkOffScreenImage) { - throw new RuntimeException (); + int dx_start, dy_start, d_width, d_height; + int sx_start, sy_start, s_width, s_height; + boolean x_flip = false; + boolean y_flip = false; + + if (dx1 < dx2) + { + dx_start = dx1; + d_width = dx2 - dx1; + } + else + { + dx_start = dx2; + d_width = dx1 - dx2; + x_flip ^= true; + } + if (dy1 < dy2) + { + dy_start = dy1; + d_height = dy2 - dy1; + } + else + { + dy_start = dy2; + d_height = dy1 - dy2; + y_flip ^= true; + } + if (sx1 < sx2) + { + sx_start = sx1; + s_width = sx2 - sx1; + } + else + { + sx_start = sx2; + s_width = sx1 - sx2; + x_flip ^= true; + } + if (sy1 < sy2) + { + sy_start = sy1; + s_height = sy2 - sy1; + } + else + { + sy_start = sy2; + s_height = sy1 - sy2; + y_flip ^= true; + } + + copyAndScalePixmap (img.getGraphics (), x_flip, y_flip, + sx_start, sy_start, s_width, s_height, + dx_start, dy_start, d_width, d_height); + return true; } GtkImage image = (GtkImage) img; Index: include/gnu_java_awt_peer_gtk_GdkGraphics.h =================================================================== RCS file: /cvsroot/classpath/classpath/include/gnu_java_awt_peer_gtk_GdkGraphics.h,v retrieving revision 1.6 diff -u -r1.6 gnu_java_awt_peer_gtk_GdkGraphics.h --- include/gnu_java_awt_peer_gtk_GdkGraphics.h 30 Jul 2004 19:28:14 -0000 1.6 +++ include/gnu_java_awt_peer_gtk_GdkGraphics.h 6 Aug 2004 00:55:05 -0000 @@ -17,6 +17,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea (JNIEnv *env, jobject, jint, jint, jint, jint, jint, jint); JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose (JNIEnv *env, jobject); JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyPixmap (JNIEnv *env, jobject, jobject, jint, jint, jint, jint); +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyAndScalePixmap(JNIEnv *env, jobject, jobject, jboolean, jboolean, jint, jint, jint, jint, jint, jint, jint, jint); JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine (JNIEnv *env, jobject, jint, jint, jint, jint); JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc (JNIEnv *env, jobject, jint, jint, jint, jint, jint, jint); JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc (JNIEnv *env, jobject, jint, jint, jint, jint, jint, jint); Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c,v retrieving revision 1.11 diff -u -r1.11 gnu_java_awt_peer_gtk_GdkGraphics.c --- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c 30 Jul 2004 16:01:47 -0000 1.11 +++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c 6 Aug 2004 00:55:06 -0000 @@ -312,7 +312,111 @@ gdk_flush (); gdk_threads_leave (); } + +static void flip_pixbuf (GdkPixbuf *pixbuf, + jboolean flip_x, + jboolean flip_y, + jint width, + jint height) +{ + gint src_rs; + guchar *src_pix; + + src_rs = gdk_pixbuf_get_rowstride (pixbuf); + src_pix = gdk_pixbuf_get_pixels (pixbuf); + + if (flip_x) + { + gint i, channels; + guchar buf[4]; + + channels = gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3; + + for (i = 0; i < height; i++) + { + guchar *left = src_pix + i * src_rs; + guchar *right = left + channels * (width - 1); + while (left < right) + { + g_memmove (buf, left, channels); + g_memmove (left, right, channels); + g_memmove (right, buf, channels); + left += channels; + right -= channels; + } + } + } + + if (flip_y) + { + guchar *top = src_pix; + guchar *bottom = top + (height - 1) * src_rs; + gpointer buf = g_malloc (src_rs); + + while (top < bottom) + { + g_memmove (buf, top, src_rs); + g_memmove (top, bottom, src_rs); + g_memmove (bottom, buf, src_rs); + top += src_rs; + bottom -= src_rs; + } + + g_free (buf); + } +} +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics_copyAndScalePixmap + (JNIEnv *env, jobject obj, jobject offscreen, jboolean flip_x, jboolean flip_y, + jint src_x, jint src_y, jint src_width, jint src_height, + jint dest_x, jint dest_y, jint dest_width, jint dest_height) +{ + struct graphics *g1, *g2; + GdkPixbuf *buf_src, *buf_dest; + + g1 = (struct graphics *) NSA_GET_PTR (env, obj); + g2 = (struct graphics *) NSA_GET_PTR (env, offscreen); + + gdk_threads_enter (); + + buf_src = gdk_pixbuf_get_from_drawable (NULL, + g2->drawable, + g2->cm, + src_x, + src_y, + 0, + 0, + src_width, + src_height); + + buf_dest = gdk_pixbuf_scale_simple (buf_src, + dest_width, + dest_height, + GDK_INTERP_BILINEAR); + + if (flip_x || flip_y) + { + flip_pixbuf (buf_dest, flip_x, flip_y, dest_width, dest_height); + } + + gdk_pixbuf_render_to_drawable (buf_dest, + g1->drawable, + g1->gc, + 0, + 0, + dest_x, + dest_y, + dest_width, + dest_height, + GDK_RGB_DITHER_NORMAL, + 0, + 0); + + g_object_unref (G_OBJECT (buf_src)); + g_object_unref (G_OBJECT (buf_dest)); + + gdk_threads_leave (); +}