OSDN Git Service

2006-08-14 Mark Wielaard <mark@klomp.org>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_CairoSurface.c
1 /* gnu_java_awt_peer_gtk_CairoSurface.c
2    Copyright (C)  2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 #include "jcl.h"
39 #include "gtkpeer.h"
40 #include <cairo-xlib.h>
41 #include <gdk/gdkx.h>
42
43 #include "gnu_java_awt_peer_gtk_CairoSurface.h"
44 #include "cairographics2d.h"
45
46 /**
47  * Field names in CairoSurface.java
48  */
49 #define SURFACE "surfacePointer"
50 #define BUFFER "bufferPointer"
51
52 /* prototypes */
53 static void setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer );
54
55 /**
56  * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha.
57  */
58 JNIEXPORT void JNICALL 
59 Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject obj, jint width, jint height, jint stride)
60 {
61   cairo_surface_t* surface;
62   void *data = g_malloc(stride * height * 4);
63   memset(data, 0, stride * height * 4);
64   setNativeObject(env, obj, data, BUFFER);
65
66   surface = cairo_image_surface_create_for_data
67     (data, CAIRO_FORMAT_ARGB32, width, height, stride * 4);
68
69   setNativeObject(env, obj, surface, SURFACE);
70 }
71
72 /**
73  * Destroy the surface
74  */
75 JNIEXPORT void JNICALL 
76 Java_gnu_java_awt_peer_gtk_CairoSurface_destroy
77 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
78  jlong surfacePointer, jlong bufferPointer)
79 {
80   void *buffer;
81   cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
82   if( surface != NULL )
83     cairo_surface_destroy(surface);
84
85   buffer = JLONG_TO_PTR(void, bufferPointer);
86   if( buffer != NULL )
87     g_free(buffer);
88 }
89
90 /**
91  * Gets a pixel
92  */
93 JNIEXPORT jint JNICALL 
94 Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem
95 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
96  jlong bufferPointer, jint i)
97 {
98   jint *pixeldata = JLONG_TO_PTR(void, bufferPointer);
99
100   if( pixeldata == NULL )
101     return 0;
102
103   return pixeldata[i];
104 }
105
106 /**
107  * Sets a pixel
108  */
109 JNIEXPORT void JNICALL 
110 Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem 
111 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
112  jlong bufferPointer, jint i, jint val)
113 {
114   jint *pixeldata = JLONG_TO_PTR(void, bufferPointer);
115
116   if( pixeldata == NULL )
117     return;
118
119   pixeldata[i] = val;
120 }
121
122 /**
123  * Gets all pixels in an array
124  */
125 JNIEXPORT jintArray JNICALL 
126 Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetPixels
127 (JNIEnv *env __attribute((unused)), jobject obj __attribute((unused)),
128  jlong bufferPointer, int size)
129 {
130   jint *pixeldata, *jpixdata;
131   jintArray jpixels;
132
133   pixeldata = JLONG_TO_PTR(void, bufferPointer);
134   g_assert(pixeldata != NULL);
135
136   jpixels = (*env)->NewIntArray (env, size);
137   jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
138   memcpy (jpixdata, pixeldata, size * sizeof( jint ));
139
140   (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
141   return jpixels;
142 }
143
144 /**
145  * Sets all pixels by an array.
146  */
147 JNIEXPORT void JNICALL 
148 Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetPixels
149 (JNIEnv *env, jobject obj, jlong bufferPointer, jintArray jpixels)
150 {
151   jint *pixeldata, *jpixdata;
152   int size;
153   int width, height;
154   jclass cls;
155   jfieldID field;
156
157   if( jpixels == NULL )
158     return;
159
160   cls = (*env)->GetObjectClass (env, obj);
161   field = (*env)->GetFieldID (env, cls, "width", "I");
162   g_assert (field != 0);
163   width = (*env)->GetIntField (env, obj, field);
164
165   field = (*env)->GetFieldID (env, cls, "height", "I");
166   g_assert (field != 0);
167   height = (*env)->GetIntField (env, obj, field);
168
169   pixeldata = JLONG_TO_PTR(void, bufferPointer);
170   g_assert(pixeldata != NULL);
171   
172   jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
173   size = (*env)->GetArrayLength( env, jpixels );
174   if( size > width * height ) size = width * height; /* stop overflows. */
175   
176   memcpy (pixeldata, jpixdata, size * sizeof( jint ));
177
178   (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
179 }
180
181 JNIEXPORT void JNICALL
182 Java_gnu_java_awt_peer_gtk_CairoSurface_nativeDrawSurface 
183 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
184  jlong surfacePointer, jlong context, jdoubleArray java_matrix, double alpha)
185 {
186   struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, context);
187   cairo_t *cr = gr->cr;
188   jdouble *native_matrix = NULL;
189   cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
190   g_assert(surface != NULL);
191   g_assert(cr != NULL);
192
193   native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
194   g_assert (native_matrix != NULL);
195   g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
196
197  {
198    cairo_matrix_t mat;
199    cairo_pattern_t *p;
200    cairo_matrix_init_identity (&mat);
201    cairo_matrix_init (&mat, 
202                       native_matrix[0], native_matrix[1],
203                       native_matrix[2], native_matrix[3],
204                       native_matrix[4], native_matrix[5]);
205
206    p = cairo_pattern_create_for_surface (surface);
207    cairo_pattern_set_matrix (p, &mat);
208
209    cairo_set_source(cr, p);
210    if (alpha == 1.0)
211      cairo_paint(cr);
212    else
213      cairo_paint_with_alpha(cr, alpha);
214
215    cairo_pattern_destroy(p);
216  }
217   
218  (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
219 }
220
221 JNIEXPORT jlong JNICALL 
222 Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer 
223 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
224  jlong bufferPointer, jint size)
225 {
226   jint *dst;
227   jint *src = JLONG_TO_PTR(void, bufferPointer);
228   int i;
229   int t;
230
231   g_assert( src != NULL );
232   dst = g_malloc( size * sizeof( jint ) );
233
234   for(i = 0; i < size; i++ )
235     {
236       t = (src[i] & 0x0000FF) << 16;
237       dst[i] = (src[i] & 0x00FF0000) >> 16;
238       dst[i] |= (src[i] & 0xFF00FF00);
239       dst[i] |= t;
240     }
241
242   return PTR_TO_JLONG(dst);
243 }
244
245 /**
246  * Create and return a cairo context for drawing to the surface.
247  */
248 JNIEXPORT jlong JNICALL 
249 Java_gnu_java_awt_peer_gtk_CairoSurface_nativeNewCairoContext
250 (JNIEnv *env __attribute((unused)), jobject obj __attribute((unused)),
251  jlong surfacePointer)
252 {
253   cairo_surface_t* surface = JLONG_TO_PTR(cairo_surface_t, surfacePointer);
254   cairo_t *ptr;
255   g_assert(surface != NULL);
256   ptr = cairo_create(surface);
257   g_assert(ptr != NULL);
258
259   return PTR_TO_JLONG(ptr);
260 }
261
262 /**
263  * copyArea.
264  */
265 JNIEXPORT void JNICALL 
266 Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative2
267 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
268  jlong bufferPointer,
269  jint x, jint y, jint w, jint h, jint dx, jint dy, jint stride)
270 {
271   int row;
272   int srcOffset, dstOffset;
273   jint *temp;
274   jint *pixeldata = JLONG_TO_PTR(jint, bufferPointer);
275   g_assert( pixeldata != NULL );
276
277   temp = g_malloc( h * w * 4 );
278   g_assert( temp != NULL );
279
280   srcOffset = x + (y * stride);
281   dstOffset = (x + dx) + ((y + dy) * stride);
282
283   for( row = 0; row < h; row++ )
284     memcpy( temp + (w * row), pixeldata + srcOffset + (stride * row), w * 4 );
285
286   for( row = 0; row < h; row++ )
287     memcpy( pixeldata + dstOffset + (stride * row), temp + (w * row), w * 4 );
288
289   g_free( temp );
290 }
291
292 /*
293  * Sets the native object field.
294  */
295 static void 
296 setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer )
297 {   
298   jclass cls;
299   jlong value;
300   jfieldID nofid;
301   cls = (*env)->GetObjectClass( env, obj );
302   value = PTR_TO_JLONG(ptr); 
303   nofid = (*env)->GetFieldID( env, cls, pointer, "J" );
304   (*env)->SetLongField( env, obj, nofid, value );
305   (*env)->DeleteLocalRef( env, cls );
306 }