This elimates the uses of GdkPixbufDecoder. Now Cairo-backed
BufferedImages are created via GtkImage.


2006-05-30  Sven de Marothy  <[EMAIL PROTECTED]>

        * gnu/java/awt/peer/gtk/CairoGraphics2D.java
        (drawImage): Use Toolkit to convert to BufferedImage.
        * gnu/java/awt/peer/gtk/CairoSurface.java
        (CairoSurface(GtkImage)): New Constructor.
        (getBufferedImage): New method.
        * gnu/java/awt/peer/gtk/ComponentGraphics.java
        Don't fill background - FIXME.
        * gnu/java/awt/peer/gtk/GdkPixbufDecoder.java:
        Remove unused methods.
        * gnu/java/awt/peer/gtk/GtkImage.java:
        (pixbuflock): New field. Methods change to use this lock.
        * gnu/java/awt/peer/gtk/GtkToolkit.java
        (createImage): Use Cairo-backed surfaces via GtkImage instead of 
        GtkPixbufDecoder.
        * native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
        (setPixels): Correct length in bytes.


Index: gnu/java/awt/peer/gtk/CairoGraphics2D.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,v
retrieving revision 1.3
diff -U3 -r1.3 CairoGraphics2D.java
--- gnu/java/awt/peer/gtk/CairoGraphics2D.java	30 May 2006 11:53:42 -0000	1.3
+++ gnu/java/awt/peer/gtk/CairoGraphics2D.java	30 May 2006 21:36:33 -0000
@@ -1025,8 +1025,8 @@
 			      invertedXform, bgcolor);
 	  }
 	else
-	  return this.drawImage(GdkPixbufDecoder.createBufferedImage(img
-								     .getSource()),
+	  return this.drawImage(Toolkit.getDefaultToolkit().
+				createImage(img.getSource()),
 				xform, bgcolor, obs);
       }
     catch (NoninvertibleTransformException e)
Index: gnu/java/awt/peer/gtk/CairoSurface.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurface.java,v
retrieving revision 1.2
diff -U3 -r1.2 CairoSurface.java
--- gnu/java/awt/peer/gtk/CairoSurface.java	30 May 2006 04:21:53 -0000	1.2
+++ gnu/java/awt/peer/gtk/CairoSurface.java	30 May 2006 21:36:33 -0000
@@ -145,6 +145,39 @@
   }
 
   /**
+   * Create a cairo_surface_t from a GtkImage instance.
+   * (data is copied, not shared)
+   */
+  CairoSurface(GtkImage image)
+  {
+    super(DataBuffer.TYPE_INT, image.width * image.height);
+
+    if(image.width <= 0 || image.height <= 0)
+      throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
+
+    width = image.width;
+    height = image.height;
+
+    create(width, height, width * 4);
+    
+    if(surfacePointer == 0 || bufferPointer == 0)
+      throw new Error("Could not allocate bitmap.");
+    
+    // Copy the pixel data from the GtkImage.
+    int[] data = image.getPixels();
+
+    // Swap ordering, since Gtk is weird.
+    for(int i = 0; i < data.length; i++ )
+      {
+	int temp = (data[i] & 0x000000FF) << 16;
+	data[i] = (data[i] & 0xFFFFFF00) | ((data[i] & 0x00FF0000) >> 16);
+	data[i] = (data[i] & 0xFF00FFFF) | temp;
+      }
+
+    setPixels( data );
+  }
+
+  /**
    * Dispose of the native data.
    */
   public void dispose()
@@ -166,8 +199,25 @@
    */    
   public static BufferedImage getBufferedImage(int width, int height)
   {
+    return getBufferedImage(new CairoSurface(width, height));
+  }
+
+  /**
+   * Returns a BufferedImage backed by a Cairo surface, 
+   * created from a GtkImage.
+   */    
+  public static BufferedImage getBufferedImage(GtkImage image)
+  {
+    return getBufferedImage(new CairoSurface(image));
+  }
+
+  /**
+   * Returns a BufferedImage backed by a Cairo surface.
+   */    
+  public static BufferedImage getBufferedImage(CairoSurface surface)
+  {
     WritableRaster raster = Raster.createPackedRaster
-      (new CairoSurface(width, height), width, height, width, 
+      (surface, surface.width, surface.height, surface.width, 
        new int[]{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
        new Point(0,0));
 
Index: gnu/java/awt/peer/gtk/ComponentGraphics.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java,v
retrieving revision 1.3
diff -U3 -r1.3 ComponentGraphics.java
--- gnu/java/awt/peer/gtk/ComponentGraphics.java	30 May 2006 19:16:56 -0000	1.3
+++ gnu/java/awt/peer/gtk/ComponentGraphics.java	30 May 2006 21:36:33 -0000
@@ -72,8 +72,8 @@
     setup( cairo_t );
     setBackground(component.awtComponent.getBackground());
     setClip(component.awtComponent.getBounds());
-    setColor( new Color( 255, 255, 255, 255 ) );
-    fill(component.awtComponent.getBounds());
+//     setColor( new Color( 255, 255, 255, 255 ) );
+//     fill(component.awtComponent.getBounds());
     setColor(component.awtComponent.getForeground());
   }
 
Index: gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java,v
retrieving revision 1.20
diff -U3 -r1.20 GdkPixbufDecoder.java
--- gnu/java/awt/peer/gtk/GdkPixbufDecoder.java	29 May 2006 16:14:59 -0000	1.20
+++ gnu/java/awt/peer/gtk/GdkPixbufDecoder.java	30 May 2006 21:36:33 -0000
@@ -683,43 +683,4 @@
       return getBufferedImage ();
     }
   }
-
-  // remaining helper class and static method is a convenience for the Gtk
-  // peers, for loading a BufferedImage in off a disk file without going
-  // through the whole imageio system. 
-
-  public static BufferedImage createBufferedImage (String filename)
-  {
-    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), 
-                                             "png", // reader auto-detects, doesn't matter
-                                             new GdkPixbufDecoder (filename));
-    return r.getBufferedImage ();
-  }
-
-  public static BufferedImage createBufferedImage (URL u)
-  {
-    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), 
-                                             "png", // reader auto-detects, doesn't matter
-                                             new GdkPixbufDecoder (u));
-    return r.getBufferedImage ();
-  }
-
-  public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset,
-                                                   int imagelength)
-  {
-    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), 
-                                             "png", // reader auto-detects, doesn't matter
-                                             new GdkPixbufDecoder (imagedata,
-                                                                   imageoffset,
-                                                                   imagelength));
-    return r.getBufferedImage ();
-  }
-  
-  public static BufferedImage createBufferedImage (ImageProducer producer)
-  {
-    GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), "png" /* ignored */, null);
-    producer.startProduction(r);
-    return r.getBufferedImage ();
-  }
-
 }
Index: gnu/java/awt/peer/gtk/GtkImage.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkImage.java,v
retrieving revision 1.32
diff -U3 -r1.32 GtkImage.java
--- gnu/java/awt/peer/gtk/GtkImage.java	30 May 2006 14:13:54 -0000	1.32
+++ gnu/java/awt/peer/gtk/GtkImage.java	30 May 2006 21:36:33 -0000
@@ -116,49 +116,57 @@
   private static GtkImage errorImage;
 
   /**
+   * Lock that should be held for all gdkpixbuf operations. We don't use
+   * the global gdk_threads_enter/leave functions in most places since
+   * most gdkpixbuf operations can be done in parallel to drawing and 
+   * manipulating gtk widgets.
+   */
+  static Object pixbufLock = new Object();
+
+  /**
    * Allocate a PixBuf from a given ARGB32 buffer pointer.
    */
   private native void initFromBuffer( long bufferPointer );
 
   /**
    * Returns a copy of the pixel data as a java array.
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   native int[] getPixels();
 
   /**
    * Sets the pixel data from a java array.
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   private native void setPixels(int[] pixels);
 
   /**
    * Loads an image using gdk-pixbuf from a file.
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   private native boolean loadPixbuf(String name);
 
   /**
    * Loads an image using gdk-pixbuf from data.
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   private native boolean loadImageFromData(byte[] data);
 
   /**
    * Allocates a Gtk Pixbuf
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   private native void createPixbuf();
 
   /**
    * Frees the above.
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   private native void freePixbuf();
 
   /**
    * Sets the pixbuf to scaled copy of src image. hints are rendering hints.
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   private native void createScaledPixbuf(GtkImage src, int hints);
 
@@ -203,7 +211,7 @@
     try
       {
 	String path = f.getCanonicalPath();
-	synchronized(GdkPixbufDecoder.pixbufLock)
+	synchronized(pixbufLock)
 	  {
 	    if (loadPixbuf(f.getCanonicalPath()) != true)
 	      throw new IllegalArgumentException("Couldn't load image: "
@@ -232,7 +240,7 @@
    */
   public GtkImage (byte[] data)
   {
-    synchronized(GdkPixbufDecoder.pixbufLock)
+    synchronized(pixbufLock)
       {
 	if (loadImageFromData (data) != true)
 	  throw new IllegalArgumentException ("Couldn't load image.");
@@ -271,7 +279,7 @@
 	throw new IllegalArgumentException ("Couldn't load image.");
       }
     byte[] array = baos.toByteArray();
-    synchronized(GdkPixbufDecoder.pixbufLock)
+    synchronized(pixbufLock)
       {
 	if (loadImageFromData(array) != true)
 	  throw new IllegalArgumentException ("Couldn't load image.");
@@ -294,7 +302,7 @@
     observers = null;
 
     // Use the GDK scaling method.
-    synchronized(GdkPixbufDecoder.pixbufLock)
+    synchronized(pixbufLock)
       {
 	createScaledPixbuf(src, hints);
       }
@@ -307,7 +315,7 @@
   GtkImage (Pointer pixbuf)
   {
     this.pixbuf = pixbuf;
-    synchronized(GdkPixbufDecoder.pixbufLock)
+    synchronized(pixbufLock)
       {
 	createFromPixbuf();
       }
@@ -348,7 +356,7 @@
 
   /**
    * Native helper function for constructor that takes a pixbuf Pointer.
-   * Should be called with the GdkPixbufDecoder.pixbufLock held.
+   * Should be called with the pixbufLock held.
    */
   private native void createFromPixbuf();
 
@@ -370,7 +378,7 @@
 
     isLoaded = true;
     deliver();
-    synchronized(GdkPixbufDecoder.pixbufLock)
+    synchronized(pixbufLock)
       {
 	createPixbuf();
 	setPixels(pixels);
@@ -413,7 +421,7 @@
       return null;
 
     int[] pixels;
-    synchronized(GdkPixbufDecoder.pixbufLock)
+    synchronized(pixbufLock)
       {
 	pixels = getPixels();
       }
@@ -458,7 +466,7 @@
       {
 	observers = new Vector();
 	isLoaded = false;
-	synchronized(GdkPixbufDecoder.pixbufLock)
+	synchronized(pixbufLock)
 	  {
 	    freePixbuf();
 	  }
@@ -470,7 +478,7 @@
   {
     if (isLoaded)
       {
-	synchronized(GdkPixbufDecoder.pixbufLock)
+	synchronized(pixbufLock)
 	  {
 	    freePixbuf();
 	  }
Index: gnu/java/awt/peer/gtk/GtkToolkit.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java,v
retrieving revision 1.84
diff -U3 -r1.84 GtkToolkit.java
--- gnu/java/awt/peer/gtk/GtkToolkit.java	25 May 2006 15:29:36 -0000	1.84
+++ gnu/java/awt/peer/gtk/GtkToolkit.java	30 May 2006 21:36:33 -0000
@@ -160,7 +160,7 @@
     Image image;
     try
       {
-        image = GdkPixbufDecoder.createBufferedImage(filename);
+	image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
       }
     catch (IllegalArgumentException iae)
       {
@@ -174,8 +174,8 @@
     Image image;
     try
       {
-        image = GdkPixbufDecoder.createBufferedImage(url);
-    }
+	image = CairoSurface.getBufferedImage( new GtkImage( url ) );
+      }
     catch (IllegalArgumentException iae)
       {
 	image = null;
@@ -188,7 +188,7 @@
     Image image;
     try
       {
-        image = GdkPixbufDecoder.createBufferedImage(producer);
+	image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
       }
     catch (IllegalArgumentException iae)
       {
@@ -203,9 +203,9 @@
     Image image;
     try
       {
-        image = GdkPixbufDecoder.createBufferedImage(imagedata,
-                                                     imageoffset,
-                                                     imagelength);
+	byte[] data = new byte[ imagelength ];
+	System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
+	image = CairoSurface.getBufferedImage( new GtkImage( data ) );
       }
     catch (IllegalArgumentException iae)
       {
@@ -222,7 +222,7 @@
    */  
   public ImageProducer createImageProducer(URL url)
   {
-    return new GdkPixbufDecoder(url);  
+    return createImage( url ).getSource();
   }
 
   /**
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
===================================================================
RCS file: /sources/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c,v
retrieving revision 1.6
diff -U3 -r1.6 gnu_java_awt_peer_gtk_CairoSurface.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c	30 May 2006 19:14:03 -0000	1.6
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c	30 May 2006 21:36:34 -0000
@@ -167,7 +167,7 @@
 
   jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
   size = (*env)->GetArrayLength( env, jpixels );
-  memcpy (pixeldata, jpixdata, size);
+  memcpy (pixeldata, jpixdata, size * sizeof( jint ));
 
 #ifndef WORDS_BIGENDIAN
   /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */

Reply via email to