This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gui][patch] fixes to buffered image painting
- From: graydon hoare <graydon at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Cc: Ziga Mahkovec <ziga dot mahkovec at klika dot si>
- Date: Mon, 06 Dec 2004 19:45:15 -0500
- Subject: [gui][patch] fixes to buffered image painting
hi,
this patch, which I've committed to java-gui-branch, fixes the
BufferedImage Graphics2D paint performance problem Ziga reported last
week. with this change, Graphics2D objects built on BufferedImages will
construct a client-side cairo context which paints directly into the
java int[] inside the image's Raster, accessed through JNI. the speed
now ranges between "the same" and "twice as fast" as sun's
BufferedImage-target painting (on gcj). it might be slower on systems in
which JNI array access involves copying arrays.
unfortunately since there's still some incomplete parts of
javax.imageio, we can't quite run bootchart yet. but it should be alive
within the next week or two.
(for the curious: the old system seemed *horribly* slow for good reason.
it involved painting to an X-server resident pixmap, copying the pixmap
back, byte swapping, and doing a color-conversion loop on the entire
image.. for each drawing operation!)
-graydon
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.
--- gnu/java/awt/peer/gtk/GdkGraphics2D.java 10 Nov 2004 07:19:46 -0000 1.7.2.22
+++ gnu/java/awt/peer/gtk/GdkGraphics2D.java 7 Dec 2004 00:29:26 -0000
@@ -78,10 +78,12 @@
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 @@
private Font font;
private RenderingHints hints;
private BufferedImage bimage;
+ private boolean pixelConversionRequired;
+ private int [] pixelBuffer;
private Composite comp;
@@ -130,9 +134,9 @@
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 @@
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 @@
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 @@
}
- 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 @@
GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
return true;
}
@@ -542,7 +563,7 @@
{
// 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 @@
walkPath (s.getPathIterator (null), shiftDrawCalls);
cairoStroke ();
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
public void fill (Shape s)
@@ -607,8 +627,7 @@
walkPath (s.getPathIterator (null), false);
cairoFill ();
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
@@ -841,7 +860,7 @@
public Shape getClip ()
{
- return getClipInDevSpace ();
+ return clip.getBounds2D(); //getClipInDevSpace ();
}
public Rectangle getClipBounds ()
@@ -904,8 +923,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,
@@ -915,8 +933,7 @@
setStroke(draw3DRectStroke);
super.fill3DRect(x, y, width, height, raised);
setStroke(tmp);
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
@@ -943,8 +960,7 @@
cairoFill ();
setColor (fg);
- if (isBufferedImageGraphics ())
- updateBufferedImage();
+ updateBufferedImage();
}
@@ -1040,45 +1056,47 @@
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 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)
--- gnu/java/awt/peer/gtk/GdkPixbufDecoder.java 7 Oct 2004 07:20:31 -0000 1.3.10.3
+++ gnu/java/awt/peer/gtk/GdkPixbufDecoder.java 7 Dec 2004 00:29:26 -0000
@@ -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) {}
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c 7 Nov 2004 14:55:38 -0000 1.5.8.13
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c 7 Dec 2004 00:29:26 -0000
@@ -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;
+
+ 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 @@
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();
}
--- jni/gtk-peer/gtkcairopeer.h 21 May 2004 23:34:16 -0000 1.1.14.1
+++ jni/gtk-peer/gtkcairopeer.h 7 Dec 2004 00:29:26 -0000
@@ -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 */