OSDN Git Service

Merged gcj-eclipse branch to trunk.
[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  jint interpolation)
186 {
187   struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, context);
188   cairo_t *cr = gr->cr;
189   jdouble *native_matrix = NULL;
190   cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
191   g_assert(surface != NULL);
192   g_assert(cr != NULL);
193
194   native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
195   g_assert (native_matrix != NULL);
196   g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
197
198  {
199    cairo_matrix_t mat;
200    cairo_pattern_t *p;
201    cairo_matrix_init_identity (&mat);
202    cairo_matrix_init (&mat, 
203                       native_matrix[0], native_matrix[1],
204                       native_matrix[2], native_matrix[3],
205                       native_matrix[4], native_matrix[5]);
206
207    p = cairo_pattern_create_for_surface (surface);
208    cairo_pattern_set_matrix (p, &mat);
209    switch ((enum java_awt_rendering_hints_filter) interpolation)
210      {
211      case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
212        cairo_pattern_set_filter (p, CAIRO_FILTER_NEAREST);
213        break;
214      case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
215        cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR);
216        break; 
217      case java_awt_rendering_hints_VALUE_INTERPOLATION_BICUBIC:
218        cairo_pattern_set_filter (p, CAIRO_FILTER_GAUSSIAN);
219        break; 
220      case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
221        cairo_pattern_set_filter (p, CAIRO_FILTER_FAST);
222        break;
223      case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
224        cairo_pattern_set_filter (p, CAIRO_FILTER_NEAREST);
225        break;
226      case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
227        cairo_pattern_set_filter (p, CAIRO_FILTER_BEST);
228        break;
229      }
230
231    cairo_set_source(cr, p);
232    if (alpha == 1.0)
233      cairo_paint(cr);
234    else
235      cairo_paint_with_alpha(cr, alpha);
236
237    cairo_pattern_destroy(p);
238  }
239   
240  (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
241 }
242
243 JNIEXPORT jlong JNICALL 
244 Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer 
245 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
246  jlong bufferPointer, jint size)
247 {
248   jint *dst;
249   jint *src = JLONG_TO_PTR(void, bufferPointer);
250   int i;
251   int t;
252
253   g_assert( src != NULL );
254   dst = g_malloc( size * sizeof( jint ) );
255
256   for(i = 0; i < size; i++ )
257     {
258       t = (src[i] & 0x0000FF) << 16;
259       dst[i] = (src[i] & 0x00FF0000) >> 16;
260       dst[i] |= (src[i] & 0xFF00FF00);
261       dst[i] |= t;
262     }
263
264   return PTR_TO_JLONG(dst);
265 }
266
267 /**
268  * Create and return a cairo context for drawing to the surface.
269  */
270 JNIEXPORT jlong JNICALL 
271 Java_gnu_java_awt_peer_gtk_CairoSurface_nativeNewCairoContext
272 (JNIEnv *env __attribute((unused)), jobject obj __attribute((unused)),
273  jlong surfacePointer)
274 {
275   cairo_surface_t* surface = JLONG_TO_PTR(cairo_surface_t, surfacePointer);
276   cairo_t *ptr;
277   g_assert(surface != NULL);
278   ptr = cairo_create(surface);
279   g_assert(ptr != NULL);
280
281   return PTR_TO_JLONG(ptr);
282 }
283
284 /**
285  * copyArea.
286  */
287 JNIEXPORT void JNICALL 
288 Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative2
289 (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
290  jlong bufferPointer,
291  jint x, jint y, jint w, jint h, jint dx, jint dy, jint stride)
292 {
293   int row;
294   int srcOffset, dstOffset;
295   jint *temp;
296   jint *pixeldata = JLONG_TO_PTR(jint, bufferPointer);
297   g_assert( pixeldata != NULL );
298
299   temp = g_malloc( h * w * 4 );
300   g_assert( temp != NULL );
301
302   srcOffset = x + (y * stride);
303   dstOffset = (x + dx) + ((y + dy) * stride);
304
305   for( row = 0; row < h; row++ )
306     memcpy( temp + (w * row), pixeldata + srcOffset + (stride * row), w * 4 );
307
308   for( row = 0; row < h; row++ )
309     memcpy( pixeldata + dstOffset + (stride * row), temp + (w * row), w * 4 );
310
311   g_free( temp );
312 }
313
314 /*
315  * Sets the native object field.
316  */
317 static void 
318 setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer )
319 {   
320   jclass cls;
321   jlong value;
322   jfieldID nofid;
323   cls = (*env)->GetObjectClass( env, obj );
324   value = PTR_TO_JLONG(ptr); 
325   nofid = (*env)->GetFieldID( env, cls, pointer, "J" );
326   (*env)->SetLongField( env, obj, nofid, value );
327   (*env)->DeleteLocalRef( env, cls );
328 }