aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libjava/ChangeLog12
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java201
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java47
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c285
-rw-r--r--libjava/jni/gtk-peer/gtkcairopeer.h13
5 files changed, 313 insertions, 245 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 95928b2cebb..c6292ae1051 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,15 @@
+2004-12-06 Graydon Hoare <graydon@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.
+
2004-12-06 Michael Koch <konqueror@gmx.de>
* javax/swing/DefaultListCellRenderer.java
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
index 82de03d5aec..0d18f173e84 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
@@ -78,10 +78,12 @@ import java.awt.image.ColorModel;
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;
import java.awt.image.ImagingOpException;
+import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.SampleModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
@@ -123,6 +125,8 @@ public class GdkGraphics2D extends Graphics2D
private Font font;
private RenderingHints hints;
private BufferedImage bimage;
+ private boolean pixelConversionRequired;
+ private int [] pixelBuffer;
private Composite comp;
@@ -130,9 +134,9 @@ public class GdkGraphics2D extends Graphics2D
native private void initState (GtkComponentPeer component);
native private void initState (int width, int height);
+ native private void initState (int[] pixes, int width, int height);
native private void copyState (GdkGraphics2D g);
native public void dispose ();
- native private int[] getImagePixels();
native private void cairoSurfaceSetFilter(int filter);
native void connectSignals (GtkComponentPeer component);
@@ -236,10 +240,24 @@ public class GdkGraphics2D extends Graphics2D
GdkGraphics2D (BufferedImage bimage)
{
- this.bimage = bimage;
- initState (bimage.getWidth(), bimage.getHeight());
+ this.bimage = bimage;
+ 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;
+ }
- setColor(Color.black);
+ initState (this.pixelBuffer,
+ bimage.getWidth(),
+ bimage.getHeight());
+
+ setColor (Color.black);
setBackground (Color.black);
setPaint (getColor());
setFont (new Font("SansSerif", Font.PLAIN, 12));
@@ -250,9 +268,9 @@ public class GdkGraphics2D extends Graphics2D
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);
}
@@ -450,52 +468,56 @@ public class GdkGraphics2D extends Graphics2D
}
- 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;
- }
-
- private final void updateImagePixels (int[] pixels)
- {
+ if (! cm.getColorSpace().isCS_sRGB())
+ return null;
- // 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 (dcm.getRedMask() != 0x00FF0000
+ || dcm.getGreenMask() != 0x0000FF00
+ || dcm.getBlueMask() != 0x000000FF)
+ return null;
- if (raster.getSampleModel ().getDataType () == DataBuffer.TYPE_INT
- && db instanceof DataBufferInt
- && db.getNumBanks () == 1)
- {
+ if (! (raster instanceof WritableRaster))
+ return null;
- // single bank, ARGB-ints buffer in sRGB space
- DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer ();
+ if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT)
+ return null;
- for (int i=0; i < pixels.length; i++)
- dbi.setElem(i, pixels[i]);
-
- }
- else
- {
- bimage.getRaster().setPixels (0, 0, raster.getWidth (),
- raster.getHeight (), pixels);
- }
+ 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.
+
+ return db.getData();
}
+ private final void updateBufferedImage()
+ {
+ if (bimage != null && pixelConversionRequired)
+ {
+ bimage.getRaster().setPixels (0, 0,
+ bimage.getRaster().getWidth (),
+ bimage.getRaster().getHeight (),
+ pixelBuffer);
+ }
+ }
private final boolean drawImage(Image img,
AffineTransform xform,
@@ -517,8 +539,7 @@ public class GdkGraphics2D extends Graphics2D
GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
return true;
}
@@ -542,7 +563,7 @@ public class GdkGraphics2D extends Graphics2D
{
// draw an image which has actually been loaded
// into memory fully
-
+
BufferedImage b = (BufferedImage) img;
return drawRaster (b.getColorModel (),
b.getData (),
@@ -591,8 +612,7 @@ public class GdkGraphics2D extends Graphics2D
walkPath (s.getPathIterator (null), shiftDrawCalls);
cairoStroke ();
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
public void fill (Shape s)
@@ -607,8 +627,7 @@ public class GdkGraphics2D extends Graphics2D
walkPath (s.getPathIterator (null), false);
cairoFill ();
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
@@ -841,7 +860,7 @@ public class GdkGraphics2D extends Graphics2D
public Shape getClip ()
{
- return getClipInDevSpace ();
+ return clip.getBounds2D(); //getClipInDevSpace ();
}
public Rectangle getClipBounds ()
@@ -904,8 +923,7 @@ public class GdkGraphics2D extends Graphics2D
setStroke(draw3DRectStroke);
super.draw3DRect(x, y, width, height, raised);
setStroke(tmp);
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
public void fill3DRect(int x, int y, int width,
@@ -915,8 +933,7 @@ public class GdkGraphics2D extends Graphics2D
setStroke(draw3DRectStroke);
super.fill3DRect(x, y, width, height, raised);
setStroke(tmp);
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
@@ -943,8 +960,7 @@ public class GdkGraphics2D extends Graphics2D
cairoFill ();
setColor (fg);
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
@@ -1040,45 +1056,47 @@ public class GdkGraphics2D extends Graphics2D
i2u[4] = 0; 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
- pixels = r.getPixels (0, 0, r.getWidth (), r.getHeight (), pixels);
-
- ColorSpace cs = cm.getColorSpace ();
- if (cs != null &&
- cs.getType () != ColorSpace.CS_sRGB)
+ if (pixels == null)
{
- int pixels2[] = new int[pixels.length];
- for (int i = 0; i < pixels2.length; i++)
- pixels2[i] = cm.getRGB (pixels[i]);
- pixels = pixels2;
+ // FIXME: I don't think this code will work correctly with a non-RGB
+ // MultiPixelPackedSampleModel. Although this entire method should
+ // probably be rewritten to better utilize Cairo's different supported
+ // data formats.
+ if (sm instanceof MultiPixelPackedSampleModel)
+ {
+ pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels);
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(pixels[i]);
+ }
+ else
+ {
+ pixels = new int[r.getWidth() * r.getHeight()];
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(db.getElem(i));
+ }
}
- // change all transparent pixels in the image to the
- // specified bgcolor
-
- if (bgcolor != null)
+ // 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)
+ for (int i = 0; i < pixels.length; i++)
+ {
+ if (cm.getAlpha (pixels[i]) == 0)
+ pixels[i] = bgcolor.getRGB ();
+ }
+ } else
for (int i = 0; i < pixels.length; i++)
- {
- if (cm.getAlpha (pixels[i]) == 0)
- pixels[i] = bgcolor.getRGB ();
- }
- }
+ pixels[i] |= 0xFF000000;
drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u);
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
return true;
}
@@ -1389,22 +1407,19 @@ public class GdkGraphics2D extends Graphics2D
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)
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
index a7b93e5b9ad..c70c62db108 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
@@ -159,15 +159,18 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
{
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 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
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) {}
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
index 176f47fe55e..aafbab7dddf 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
@@ -175,7 +175,6 @@ x_server_has_render_extension (void)
return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
}
-
static void
init_graphics2d_as_pixbuf (struct graphics2d *gr)
{
@@ -196,13 +195,14 @@ init_graphics2d_as_pixbuf (struct graphics2d *gr)
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 @@ init_graphics2d_as_renderable (struct graphics2d *gr)
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;
+
+ 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;
- 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);
+ 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 @@ check_for_debug (struct graphics2d *gr)
}
static void
-realize_cb (GtkWidget *widget, jobject peer)
+realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject peer)
{
gdk_threads_leave ();
@@ -342,18 +381,29 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
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;
+
+ 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_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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
if (src->debug) printf ("copying from offscreen drawable\n");
- begin_drawing_operation(dst);
+ begin_drawing_operation(env, dst);
/* gdk_flush(); */
@@ -439,7 +520,7 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
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 @@ ensure_metrics_cairo()
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerTextMetrics
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerTextMetrics
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerFontMetrics
}
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 @@ paint_glyph_run(struct graphics2d *gr,
}
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawString
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkGlyphVector
/* 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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout
{
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
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 @@ Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
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();
}
diff --git a/libjava/jni/gtk-peer/gtkcairopeer.h b/libjava/jni/gtk-peer/gtkcairopeer.h
index b4021f51ed9..85834cadb02 100644
--- a/libjava/jni/gtk-peer/gtkcairopeer.h
+++ b/libjava/jni/gtk-peer/gtkcairopeer.h
@@ -74,6 +74,19 @@ struct graphics2d
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 */