[kaffe] CVS kaffe (robilad): Resynced with GNU Classpath: painting fixes

Kaffe CVS cvs-commits at kaffe.org
Wed Jan 5 10:34:13 PST 2005


PatchSet 5761 
Date: 2005/01/05 18:29:29
Author: robilad
Branch: HEAD
Tag: (none) 
Log:
Resynced with GNU Classpath: painting fixes

Members: 
	ChangeLog:1.3305->1.3306 
	libraries/clib/awt/classpath-gtk/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:1.7->1.8 
	libraries/clib/awt/classpath-gtk/gtk-peer/gtkcairopeer.h:1.1->1.2 
	libraries/javalib/gnu/java/awt/peer/gtk/GdkGraphics2D.java:1.11->1.12 
	libraries/javalib/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:1.3->1.4 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3305 kaffe/ChangeLog:1.3306
--- kaffe/ChangeLog:1.3305	Wed Jan  5 18:06:25 2005
+++ kaffe/ChangeLog	Wed Jan  5 18:29:29 2005
@@ -1,5 +1,21 @@
 2005-01-05  Dalibor Topic  <robilad at kaffe.org>
 
+	Resynced with GNU Classpath.
+	
+	2004-12-26  Graydon Hoare  <graydon at redhat.com>
+
+	* gnu/java/awt/peer/gtk/GdkGraphics2D.java:
+	Rework painting into BufferedImages
+	* gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:
+	Construct BufferedImage with alpha only when alpha is
+	present in colormodel.
+	* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:
+	Rework painting into client-side jint arrays.
+	* jni/gtk-peer/gtkcairopeer.h:
+	Likewise.
+
+2005-01-05  Dalibor Topic  <robilad at kaffe.org>
+
 	* libraries/javalib/gnu/java/awt/peer/gtk/GdkGraphics2D.java:
 	Resynced with GNU Classpath.
 
Index: kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
diff -u kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:1.7 kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:1.8
--- kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:1.7	Fri Oct 29 21:36:57 2004
+++ kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c	Wed Jan  5 18:29:32 2005
@@ -175,7 +175,6 @@
   return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
 }
 
-
 static void
 init_graphics2d_as_pixbuf (struct graphics2d *gr)
 {
@@ -196,13 +195,14 @@
   g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample);
   g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels);
   
-  gr->surface = cairo_surface_create_for_image (gdk_pixbuf_get_pixels (gr->drawbuf), 
+  gr->surface = cairo_surface_create_for_image ((char *) gdk_pixbuf_get_pixels (gr->drawbuf), 
 						CAIRO_FORMAT_ARGB32, 
 						gdk_pixbuf_get_width (gr->drawbuf), 
 						gdk_pixbuf_get_height (gr->drawbuf), 
 						gdk_pixbuf_get_rowstride (gr->drawbuf));      
   g_assert (gr->surface != NULL);
   g_assert (gr->cr != NULL);
+  gr->mode = MODE_DRAWABLE_NO_RENDER;
   cairo_set_target_surface (gr->cr, gr->surface);
 }
 
@@ -232,60 +232,99 @@
 					   DefaultColormap (dpy, DefaultScreen (dpy)));
   g_assert (gr->surface != NULL);
   g_assert (gr->cr != NULL);
+  gr->mode = MODE_DRAWABLE_WITH_RENDER;
   cairo_set_target_surface (gr->cr, gr->surface);
 }
 
 static void
-begin_drawing_operation (struct graphics2d * gr)
+begin_drawing_operation (JNIEnv *env, struct graphics2d * gr)
 {  
   g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
-  if (gr->drawbuf)
+
+  switch (gr->mode)
     {
+    case MODE_DRAWABLE_WITH_RENDER:
+      break;
 
-      gint drawable_width, drawable_height;
-      gint pixbuf_width, pixbuf_height;
-      gint width, height;
-      
-      gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
-      pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
-      pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
-      width = min (drawable_width, pixbuf_width);
-      height = min (drawable_height, pixbuf_height);
-
-      gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
-				    gr->drawable, 
-				    NULL, /* colormap */
-				    0, 0, 0, 0,
-				    width, height); 
-      
-      if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
-			     width, height);      
+    case MODE_DRAWABLE_NO_RENDER:
+      {
+	
+	gint drawable_width, drawable_height;
+	gint pixbuf_width, pixbuf_height;
+	gint width, height;
+	
+	gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
+	pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
+	pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
+	width = min (drawable_width, pixbuf_width);
+	height = min (drawable_height, pixbuf_height);
+	
+	gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
+				      gr->drawable, 
+				      NULL, /* colormap */
+				      0, 0, 0, 0,
+				      width, height); 
+	
+	if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
+			       width, height);      
+      }
+      break;
+
+    case MODE_JAVA_ARRAY:
+      gr->javabuf = (*env)->GetIntArrayElements (env, gr->jarray, &gr->isCopy);
+      gr->surface = cairo_surface_create_for_image ((char *) gr->javabuf, 
+						    CAIRO_FORMAT_ARGB32, 
+						    gr->width, 
+						    gr->height, 
+						    gr->width * 4);
+      g_assert(gr->surface != NULL);
+      g_assert(gr->cr != NULL);
+      cairo_set_target_surface (gr->cr, gr->surface);
+      break;
     }
 }
 
 static void
-end_drawing_operation (struct graphics2d * gr)
+end_drawing_operation (JNIEnv *env, struct graphics2d * gr)
 {
   g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
-  if (gr->drawbuf)
-    { 
-      gint drawable_width, drawable_height;
-      gint pixbuf_width, pixbuf_height;
-      gint width, height;
-      
-      gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
-      pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
-      pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
-      width = min (drawable_width, pixbuf_width);
-      height = min (drawable_height, pixbuf_height);
-
-      gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
-		       0, 0, 0, 0, 
-		       width, height, 
-		       GDK_RGB_DITHER_NORMAL, 0, 0);
 
-      if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
-			     width, height);
+  switch (gr->mode)
+    {
+    case MODE_DRAWABLE_WITH_RENDER:
+      break;
+
+    case MODE_DRAWABLE_NO_RENDER:
+      {
+
+	gint drawable_width, drawable_height;
+	gint pixbuf_width, pixbuf_height;
+	gint width, height;
+	
+	gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
+	pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
+	pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
+	width = min (drawable_width, pixbuf_width);
+	height = min (drawable_height, pixbuf_height);
+	
+	gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
+			 0, 0, 0, 0, 
+			 width, height, 
+			 GDK_RGB_DITHER_NORMAL, 0, 0);
+	
+	if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
+			       width, height);
+      }
+      break;
+      
+    case MODE_JAVA_ARRAY:
+      /* 
+       * FIXME: Perhaps this should use the isCopy flag to try to avoid
+       * tearing down the cairo surface.
+       */
+      cairo_surface_destroy (gr->surface);
+      gr->surface = NULL;
+      (*env)->ReleaseIntArrayElements (env, gr->jarray, gr->javabuf, JNI_COMMIT);
     }
 }
 
@@ -317,7 +356,7 @@
 }
 
 static void
-realize_cb (GtkWidget *widget, jobject peer)
+realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject peer)
 {
   gdk_threads_leave ();
 
@@ -342,18 +381,29 @@
 
   if (g_old->debug) printf ("copying state from existing graphics2d\n");
 
-  g->drawable = g_old->drawable;
   g->debug = g_old->debug; 
+  g->mode = g_old->mode;
 
-  g_object_ref (g->drawable);
+  if (g_old->mode == MODE_JAVA_ARRAY)
+    {
+      g->width = g_old->width;
+      g->height = g_old->height;
+      g->jarray = (*env)->NewGlobalRef(env, g_old->jarray);
+    }
+  else
+    {
+      g->drawable = g_old->drawable;
+
+      g_object_ref (g->drawable);
   
-  g->cr = cairo_create();
-  g_assert (g->cr != NULL);
+      g->cr = cairo_create();
+      g_assert (g->cr != NULL);
 
-  if (x_server_has_render_extension ())
-    init_graphics2d_as_renderable (g);
-  else
-    init_graphics2d_as_pixbuf (g);
+      if (x_server_has_render_extension ())
+	init_graphics2d_as_renderable (g);
+      else
+	init_graphics2d_as_pixbuf (g);
+    }
 
   cairo_surface_set_filter (g->surface, CAIRO_FILTER_FAST);
 
@@ -363,6 +413,37 @@
 
 
 JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III
+(JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height)
+{
+  struct graphics2d *gr;
+
+  gdk_threads_enter();
+  gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
+  g_assert (gr != NULL);
+  memset (gr, 0, sizeof(struct graphics2d));
+
+  check_for_debug (gr);  
+
+  if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n",
+			 width, height);
+  
+  gr->cr = cairo_create();
+  g_assert (gr->cr != NULL);
+
+  gr->width = width;
+  gr->height = height;
+  gr->jarray = (*env)->NewGlobalRef(env, jarr);
+  gr->mode = MODE_JAVA_ARRAY;
+
+  if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n",
+			 width, height);
+
+  NSA_SET_G2D_PTR (env, obj, gr);
+  gdk_threads_leave();  
+}
+
+JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
   (JNIEnv *env, jobject obj, jint width, jint height)
 {
@@ -414,7 +495,7 @@
 
   if (src->debug) printf ("copying from offscreen drawable\n");
 
-  begin_drawing_operation(dst); 
+  begin_drawing_operation(env, dst); 
 
   /* gdk_flush(); */
 
@@ -439,7 +520,7 @@
 
   gdk_flush();
 
-  end_drawing_operation(dst);
+  end_drawing_operation(env, dst);
 
   if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
   gdk_threads_leave();
@@ -531,6 +612,9 @@
   if (gr->pattern_pixels)
     free (gr->pattern_pixels);
 
+  if (gr->mode == MODE_JAVA_ARRAY)
+    (*env)->DeleteGlobalRef(env, gr->jarray);
+
   if (gr->debug) printf ("disposed of graphics2d\n");
 
   free (gr);
@@ -734,7 +818,7 @@
   g_assert (native_matrix != NULL);
   g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
 
-  begin_drawing_operation (gr);
+  begin_drawing_operation (env, gr);
   
  {
    cairo_matrix_t *mat = NULL;
@@ -748,13 +832,12 @@
 			    native_matrix[4], native_matrix[5]);
    cairo_surface_set_matrix (surf, mat);
    cairo_surface_set_filter (surf, cairo_surface_get_filter(gr->surface));
-
    cairo_show_surface (gr->cr, surf, w, h);
    cairo_matrix_destroy (mat);
    cairo_surface_destroy (surf);
  }
   
- end_drawing_operation (gr);
+ end_drawing_operation (env, gr);
  
  (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
  (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
@@ -762,65 +845,6 @@
   gdk_threads_leave();
 }
 
-JNIEXPORT jintArray JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getImagePixels 
-   (JNIEnv *env, jobject obj)
-{
-  struct graphics2d *gr = NULL;
-  jintArray java_pixels;
-  jint* native_pixels;
-  GdkPixbuf *buf = NULL;
-  gint width, height;
-  gint bits_per_sample = 8;
-  gboolean has_alpha = TRUE;
-  gint total_channels = 4;
-  jint i;
-
-  gdk_threads_enter();
-  if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return NULL; }
-
-  gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-  g_assert (gr != NULL);
-  
-  if (gr->debug) printf ("getImagePixels\n");
-  
-  gdk_drawable_get_size (gr->drawable, &width, &height);
-    
-  buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 
-                        bits_per_sample,
-                        width, height);
-  g_assert (buf != NULL);
-  g_assert (gdk_pixbuf_get_bits_per_sample (buf) == bits_per_sample);
-  g_assert (gdk_pixbuf_get_n_channels (buf) == total_channels);
-  
-      
-  /* copy pixels from drawable to pixbuf */
-  
-  gdk_pixbuf_get_from_drawable (buf, gr->drawable,
-                                NULL, 
-                                0, 0, 0, 0,
-                                width, height);
- 								      				      
-  native_pixels= gdk_pixbuf_get_pixels (buf);
-
-#ifndef WORDS_BIGENDIAN
-  /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
-  for (i=0; i<width * height; i++)
-    {
-      native_pixels[i] = SWAPU32 ((unsigned)native_pixels[i]);
-    }
-#endif
-
-   java_pixels = (*env) -> NewIntArray (env, width * height);   
-   
-   (*env)->SetIntArrayRegion(env, java_pixels, 
-                            (jsize)0, (jsize) width*height, 
-                            (jint*) native_pixels);
-   
-   gdk_threads_leave();
-   return java_pixels;
-}
-
 /* passthrough methods to cairo */
 
 JNIEXPORT void JNICALL
@@ -952,7 +976,7 @@
 
 JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
-   (JNIEnv *env, jclass clazz, jobject java_font)
+   (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font)
 {
   struct peerfont *pfont = NULL;
 
@@ -971,7 +995,7 @@
 
 JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerTextMetrics
-   (JNIEnv *env, jclass clazz, jobject java_font, jstring str, jdoubleArray java_metrics)
+   (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font, jstring str, jdoubleArray java_metrics)
 {
   struct peerfont *pfont = NULL;
   const char *cstr = NULL;
@@ -989,7 +1013,7 @@
 
   cstr = (*env)->GetStringUTFChars (env, str, NULL);
   g_assert(cstr != NULL);
-  cairo_text_extents (metrics_cairo, cstr, &extents);
+  cairo_text_extents (metrics_cairo, (unsigned char *) cstr, &extents);
 
   native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
   g_assert (native_metrics != NULL);
@@ -1008,7 +1032,7 @@
 
 JNIEXPORT void JNICALL
 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerFontMetrics
-   (JNIEnv *env, jclass clazz, jobject java_font, jdoubleArray java_metrics)
+   (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font, jdoubleArray java_metrics)
 {
   struct peerfont *pfont = NULL;
   jdouble *native_metrics = NULL;
@@ -1042,7 +1066,8 @@
 }
 
 static void
-paint_glyph_run(struct graphics2d *gr,
+paint_glyph_run(JNIEnv *env,
+		struct graphics2d *gr,
 		cairo_glyph_t **glyphs,
 		gint *n_glyphs,
 		PangoLayoutRun *run)
@@ -1090,9 +1115,9 @@
 	}
 
       if (gr->debug) printf("\n");
-      begin_drawing_operation (gr);
+      begin_drawing_operation (env, gr);
       cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs);
-      end_drawing_operation (gr);      
+      end_drawing_operation (env, gr);      
     }
 }
 
@@ -1138,7 +1163,7 @@
 
   install_font_peer (gr->cr, pfont, gr->debug);
   cairo_move_to (gr->cr, x, y);
-  cairo_show_text (gr->cr, cstr);
+  cairo_show_text (gr->cr, (unsigned char *) cstr);
   
   /*
     
@@ -1206,7 +1231,7 @@
   /* nb. PangoLayoutRun is a typedef for PangoGlyphItem. */
   run = (PangoLayoutRun *) gv->glyphitems;
   if (run != NULL)
-    paint_glyph_run (gr, &glyphs, &n_glyphs, run);
+    paint_glyph_run (env, gr, &glyphs, &n_glyphs, run);
 
   if (glyphs != NULL)
     g_free (glyphs);
@@ -1259,7 +1284,7 @@
     {
       run = pango_layout_iter_get_run (i);
       if (run != NULL)
-	paint_glyph_run (gr, &glyphs, &n_glyphs, run);
+	paint_glyph_run (env, gr, &glyphs, &n_glyphs, run);
     } 
   while (pango_layout_iter_next_run (i));
   
@@ -1671,9 +1696,9 @@
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_stroke\n");
-  begin_drawing_operation (gr);
+  begin_drawing_operation (env, gr);
   cairo_stroke (gr->cr);
-  end_drawing_operation (gr);
+  end_drawing_operation (env, gr);
   gdk_threads_leave();
 }
 
@@ -1689,9 +1714,9 @@
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
   if (gr->debug) printf ("cairo_fill\n");
-  begin_drawing_operation (gr);
+  begin_drawing_operation (env, gr);
   cairo_fill (gr->cr);
-  end_drawing_operation (gr);
+  end_drawing_operation (env, gr);
   gdk_threads_leave();
 }
 
@@ -1707,10 +1732,10 @@
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   if (gr == NULL) { gdk_threads_leave (); return; }
   if (gr->debug) printf ("cairo_clip\n");
-  begin_drawing_operation (gr);
+  begin_drawing_operation (env, gr);
   cairo_init_clip (gr->cr);
   cairo_clip (gr->cr);
-  end_drawing_operation (gr);
+  end_drawing_operation (env, gr);
   gdk_threads_leave();
 }
 
Index: kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gtkcairopeer.h
diff -u kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gtkcairopeer.h:1.1 kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gtkcairopeer.h:1.2
--- kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gtkcairopeer.h:1.1	Thu Jul 22 19:04:02 2004
+++ kaffe/libraries/clib/awt/classpath-gtk/gtk-peer/gtkcairopeer.h	Wed Jan  5 18:29:33 2005
@@ -74,6 +74,19 @@
   cairo_surface_t *pattern_surface;
   cairo_pattern_t *pattern;
   gboolean debug;
+  enum 
+    { 
+      MODE_DRAWABLE_WITH_RENDER,
+      MODE_DRAWABLE_NO_RENDER,
+      MODE_JAVA_ARRAY
+    } 
+  mode;
+
+  /* Support for MODE_JAVA_ARRAY */
+  jintArray jarray;
+  jint width, height;
+  jint *javabuf;
+  jboolean isCopy;
 };
 
 #endif /* __GTKCAIROPEER_H */
Index: kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkGraphics2D.java
diff -u kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkGraphics2D.java:1.11 kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkGraphics2D.java:1.12
--- kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkGraphics2D.java:1.11	Wed Jan  5 18:06:28 2005
+++ kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkGraphics2D.java	Wed Jan  5 18:29:33 2005
@@ -78,6 +78,7 @@
 import java.awt.image.CropImageFilter;
 import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferInt;
+import java.awt.image.DirectColorModel;
 import java.awt.image.FilteredImageSource;
 import java.awt.image.ImageConsumer;
 import java.awt.image.ImageObserver;
@@ -123,14 +124,16 @@
   private Font font;
   private RenderingHints hints;
   private BufferedImage bimage;
+  private boolean pixelConversionRequired;
+  private int[] pixelBuffer;
   private Composite comp;
   private Stack stateStack;
 
   private native void initState(GtkComponentPeer component);
   private native void initState(int width, int height);
+  private native void initState(int[] pixes, int width, int height);
   private native void copyState(GdkGraphics2D g);
   public native void dispose();
-  private native int[] getImagePixels();
   private native void cairoSurfaceSetFilter(int filter);
   native void connectSignals(GtkComponentPeer component);
 
@@ -234,7 +237,20 @@
   GdkGraphics2D(BufferedImage bimage)
   {
     this.bimage = bimage;
-    initState(bimage.getWidth(), bimage.getHeight());
+    this.pixelBuffer = findSimpleIntegerArray(bimage.getColorModel(),
+                                              bimage.getRaster());
+    if (this.pixelBuffer == null)
+      {
+	this.pixelBuffer = new int[bimage.getRaster().getWidth() * bimage.getRaster()
+	                                                                 .getHeight()];
+	this.pixelConversionRequired = true;
+      }
+    else
+      {
+        this.pixelConversionRequired = false;
+      }
+
+    initState(this.pixelBuffer, bimage.getWidth(), bimage.getHeight());
 
     setColor(Color.black);
     setBackground(Color.black);
@@ -247,8 +263,9 @@
     stateStack = new Stack();
 
     // draw current buffered image to the pixmap associated 
-    // with it.
-    drawImage(bimage, new AffineTransform(1, 0, 0, 1, 0, 0), bg, null);
+    // with it, if the image is not equal to our paint buffer.
+    if (pixelConversionRequired)
+      drawImage(bimage, new AffineTransform(1, 0, 0, 1, 0, 0), bg, null);
   }
 
   ////////////////////////////////////
@@ -434,41 +451,54 @@
     return defaultHints;
   }
 
-  private final void updateBufferedImage()
+  private final int[] findSimpleIntegerArray(ColorModel cm, Raster raster)
   {
-    int[] pixels = getImagePixels();
-    updateImagePixels(pixels);
-  }
+    if (cm == null || raster == null)
+      return null;
 
-  private final boolean isBufferedImageGraphics()
-  {
-    return bimage != null;
-  }
+    if (! cm.getColorSpace().isCS_sRGB())
+      return null;
 
-  private final void updateImagePixels(int[] pixels)
-  {
-    // This function can only be used if 
-    // this graphics object is used to draw into 
-    // buffered image 
-    if (! isBufferedImageGraphics())
-      return;
+    if (! (cm instanceof DirectColorModel))
+      return null;
 
-    WritableRaster raster = bimage.getRaster();
-    DataBuffer db = raster.getDataBuffer();
+    DirectColorModel dcm = (DirectColorModel) cm;
 
-    // update pixels in the bufferedImage
-    if (raster.getSampleModel().getDataType() == DataBuffer.TYPE_INT
-        && db instanceof DataBufferInt && db.getNumBanks() == 1)
-      {
-	// single bank, ARGB-ints buffer in sRGB space
-	DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer();
+    if (dcm.getRedMask() != 0x00FF0000 || dcm.getGreenMask() != 0x0000FF00
+        || dcm.getBlueMask() != 0x000000FF)
+      return null;
+
+    if (! (raster instanceof WritableRaster))
+      return null;
+
+    if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT)
+      return null;
+
+    if (! (raster.getDataBuffer() instanceof DataBufferInt))
+      return null;
+
+    DataBufferInt db = (DataBufferInt) raster.getDataBuffer();
+
+    if (db.getNumBanks() != 1)
+      return null;
+
+    // Finally, we have determined that this is a single bank, [A]RGB-int
+    // buffer in sRGB space. It's worth checking all this, because it means
+    // that cairo can paint directly into the data buffer, which is very
+    // fast compared to all the normal copying and converting.
 
-	for (int i = 0; i < pixels.length; i++)
-	  dbi.setElem(i, pixels[i]);
+    return db.getData();
+  }
+
+  private final void updateBufferedImage()
+  {
+    if (bimage != null && pixelConversionRequired)
+      {
+        bimage.getRaster().setPixels(0, 0, 
+                                     bimage.getRaster().getWidth (),
+                                     bimage.getRaster().getHeight (), 
+                                     pixelBuffer);
       }
-    else
-      bimage.getRaster().setPixels(0, 0, raster.getWidth(),
-                                   raster.getHeight(), pixels);
   }
 
   private final boolean drawImage(Image img, AffineTransform xform,
@@ -487,8 +517,7 @@
 	gdkDrawDrawable(g2, (int) xform.getTranslateX(),
 	                (int) xform.getTranslateY());
 
-	if (isBufferedImageGraphics())
-	  updateBufferedImage();
+	updateBufferedImage();
 
 	return true;
       }
@@ -552,8 +581,7 @@
       walkPath(s.getPathIterator(null), shiftDrawCalls);
     cairoStroke();
 
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void fill(Shape s)
@@ -569,8 +597,7 @@
 
     cairoFill();
 
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void clip(Shape s)
@@ -793,7 +820,7 @@
 
   public Shape getClip()
   {
-    return getClipInDevSpace();
+    return clip.getBounds2D(); //getClipInDevSpace();
   }
 
   public Rectangle getClipBounds()
@@ -857,8 +884,7 @@
     setStroke(draw3DRectStroke);
     super.draw3DRect(x, y, width, height, raised);
     setStroke(tmp);
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void fill3DRect(int x, int y, int width, int height, boolean raised)
@@ -867,8 +893,7 @@
     setStroke(draw3DRectStroke);
     super.fill3DRect(x, y, width, height, raised);
     setStroke(tmp);
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void drawRect(int x, int y, int width, int height)
@@ -893,8 +918,7 @@
     cairoFill();
     setColor(fg);
 
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void setBackground(Color c)
@@ -989,16 +1013,9 @@
 	i2u[5] = 0;
       }
 
-    int[] pixels = null;
+    int[] pixels = findSimpleIntegerArray(cm, r);
 
-    if (sm.getDataType() == DataBuffer.TYPE_INT && db instanceof DataBufferInt
-        && db.getNumBanks() == 1)
-      {
-	// single bank, ARGB-ints buffer in sRGB space
-	DataBufferInt dbi = (DataBufferInt) db;
-	pixels = dbi.getData();
-      }
-    else
+    if (pixels == null)
       {
 	// FIXME: I don't think this code will work correctly with a non-RGB
 	// MultiPixelPackedSampleModel. Although this entire method should 
@@ -1018,8 +1035,9 @@
 	  }
       }
 
-    // change all transparent pixels in the image to the 
-    // specified bgcolor            
+    // Change all transparent pixels in the image to the specified bgcolor,
+    // or (if there's no alpha) fill in an alpha channel so that it paints
+    // correctly.
     if (cm.hasAlpha())
       {
 	if (bgcolor != null && cm.hasAlpha())
@@ -1035,8 +1053,7 @@
 
     drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u);
 
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
 
     return true;
   }
@@ -1320,22 +1337,19 @@
   public void drawGdkGlyphVector(GdkGlyphVector gv, float x, float y)
   {
     cairoDrawGdkGlyphVector(getFontPeer(), gv, x, y);
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void drawGdkTextLayout(GdkTextLayout gl, float x, float y)
   {
     cairoDrawGdkTextLayout(getFontPeer(), gl, x, y);
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void drawString(String str, float x, float y)
   {
     cairoDrawString(getFontPeer(), str, x, y);
-    if (isBufferedImageGraphics())
-      updateBufferedImage();
+    updateBufferedImage();
   }
 
   public void drawString(String str, int x, int y)
Index: kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
diff -u kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:1.3 kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:1.4
--- kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:1.3	Mon Oct  4 13:32:33 2004
+++ kaffe/libraries/javalib/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java	Wed Jan  5 18:29:33 2005
@@ -159,15 +159,18 @@
   {
     BufferedImage bufferedImage;
     ColorModel defaultModel;
+    int width;
+    int height;
 
     public BufferedImage getBufferedImage()
     {
       return bufferedImage;
     }
 
-    public void setDimensions(int width, int height)
+    public void setDimensions(int w, int h)
     {
-      bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB);
+      width = w;
+      height = h;
     }
     
     public void setProperties(Hashtable props) {}
@@ -189,28 +192,28 @@
                           ColorModel model, int[] pixels, 
                           int offset, int scansize)
     {
-      if (bufferedImage != null)
+      if (model == null)
+        model = defaultModel;
+      
+      if (bufferedImage == null)
+        bufferedImage = new BufferedImage (width, height, (model != null && model.hasAlpha() ? 
+                                                           BufferedImage.TYPE_INT_ARGB
+                                                           : BufferedImage.TYPE_INT_RGB));
+      int pixels2[];
+      if (model != null)
         {
-
-          if (model == null)
-            model = defaultModel;
-
-          int pixels2[];
-          if (model != null)
-            {
-              pixels2 = new int[pixels.length];
-              for (int yy = 0; yy < h; yy++)
-                for (int xx = 0; xx < w; xx++)
-                  {
-                    int i = yy * scansize + xx;
-                    pixels2[i] = model.getRGB (pixels[i]);
-                  }
-            }
-          else
-            pixels2 = pixels;
-
-          bufferedImage.setRGB (x, y, w, h, pixels2, offset, scansize);
+          pixels2 = new int[pixels.length];
+          for (int yy = 0; yy < h; yy++)
+            for (int xx = 0; xx < w; xx++)
+              {
+                int i = yy * scansize + xx;
+                pixels2[i] = model.getRGB (pixels[i]);
+              }
         }
+      else
+        pixels2 = pixels;
+
+      bufferedImage.setRGB (x, y, w, h, pixels2, offset, scansize);
     }
 
     public void imageComplete(int status) {}




More information about the kaffe mailing list