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 */