This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI [gui] Add support for scaling pixmaps


Hi,

This adds the work of Craig Black done on GNU Classpath.
The attached patch adds support for scaling pixmaps as used in two of
the Graphics.drawImage methods. Currently those methods throw
RuntimeExceptions when using offscreen images.

2004-08-09  Craig Black  <craig.black@aonix.com>

       * gnu/java/awt/peer/gtk/GdkGraphics.java 
       (drawImage): Add support for scaling pixmaps.
       * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
       (copyAndScalePixmap): New native method.

This makes the smiley example work perfectly :)
http://lists.gnu.org/archive/html/classpath-patches/2004-08/txtoVfj96Rv0S.txt

Committed to the gui branch.

Cheers,

Mark
Index: gnu/java/awt/peer/gtk/GdkGraphics.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java,v
retrieving revision 1.4.16.5
diff -u -r1.4.16.5 GdkGraphics.java
--- gnu/java/awt/peer/gtk/GdkGraphics.java	30 Jul 2004 19:29:40 -0000	1.4.16.5
+++ gnu/java/awt/peer/gtk/GdkGraphics.java	9 Aug 2004 22:34:31 -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: jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c,v
retrieving revision 1.5.2.5
diff -u -r1.5.2.5 gnu_java_awt_peer_gtk_GdkGraphics.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c	24 Jul 2004 04:27:01 -0000	1.5.2.5
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c	9 Aug 2004 22:34:31 -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 ();
+}
 
 
 

Attachment: signature.asc
Description: This is a digitally signed message part


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]