Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GdkGraphics2D.c
blobc95ea614b7ac22efc26c8c6e4b44a7f37494b2fc
1 /* gnu_java_awt_peer_gtk_GdkGraphics2d.c
2 Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
38 #include "jcl.h"
39 #include "gtkcairopeer.h"
40 #include "gdkfont.h"
41 #include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
42 #include <gdk/gdktypes.h>
43 #include <gdk/gdkprivate.h>
44 #include <gdk/gdkx.h>
45 #include <X11/extensions/Xrender.h>
47 #include <gdk-pixbuf/gdk-pixbuf.h>
48 #include <gdk-pixbuf/gdk-pixdata.h>
50 #include <cairo-ft.h>
51 #include <cairo-xlib.h>
53 #include <stdio.h>
54 #include <stdlib.h>
56 static jmethodID initComponentGraphics2DUnlockedID;
58 void
59 cp_gtk_graphics2d_init_jni (void)
61 jclass gdkgraphics2d;
62 JNIEnv *env = cp_gtk_gdk_env();
64 gdkgraphics2d = (*env)->FindClass (env,
65 "gnu/java/awt/peer/gtk/GdkGraphics2D");
66 if ((*env)->ExceptionOccurred(env))
67 return;
69 initComponentGraphics2DUnlockedID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics2d,
70 "initComponentGraphics2DUnlocked",
71 "()V");
74 static struct state_table *native_graphics2d_state_table;
76 #define NSA_G2D_INIT(env, clazz) \
77 native_graphics2d_state_table = cp_gtk_init_state_table (env, clazz)
79 #define NSA_GET_G2D_PTR(env, obj) \
80 cp_gtk_get_state (env, obj, native_graphics2d_state_table)
82 #define NSA_SET_G2D_PTR(env, obj, ptr) \
83 cp_gtk_set_state (env, obj, native_graphics2d_state_table, (void *)ptr)
85 #define NSA_DEL_G2D_PTR(env, obj) \
86 cp_gtk_remove_state_slot (env, obj, native_graphics2d_state_table)
88 JNIEXPORT void JNICALL
89 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState
90 (JNIEnv *env, jclass clazz)
92 gdk_threads_enter();
94 NSA_G2D_INIT (env, clazz);
96 gdk_threads_leave();
99 /* these public final constants are part of the java2d public API, so we
100 write them explicitly here to save fetching them from the constant pool
101 all the time. */
103 #ifndef min
104 #define min(x,y) ((x) < (y) ? (x) : (y))
105 #endif
107 enum java_awt_alpha_composite_rule
109 java_awt_alpha_composite_CLEAR = 1,
110 java_awt_alpha_composite_SRC = 2,
111 java_awt_alpha_composite_SRC_OVER = 3,
112 java_awt_alpha_composite_DST_OVER = 4,
113 java_awt_alpha_composite_SRC_IN = 5,
114 java_awt_alpha_composite_DST_IN = 6,
115 java_awt_alpha_composite_SRC_OUT = 7,
116 java_awt_alpha_composite_DST_OUT = 8,
117 java_awt_alpha_composite_DST = 9,
118 java_awt_alpha_composite_SRC_ATOP = 10,
119 java_awt_alpha_composite_DST_ATOP = 11,
120 java_awt_alpha_composite_XOR = 12
123 enum java_awt_basic_stroke_join_rule
125 java_awt_basic_stroke_JOIN_MITER = 0,
126 java_awt_basic_stroke_JOIN_ROUND = 1,
127 java_awt_basic_stroke_JOIN_BEVEL = 2
130 enum java_awt_basic_stroke_cap_rule
132 java_awt_basic_stroke_CAP_BUTT = 0,
133 java_awt_basic_stroke_CAP_ROUND = 1,
134 java_awt_basic_stroke_CAP_SQUARE = 2
137 enum java_awt_geom_path_iterator_winding_rule
139 java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
140 java_awt_geom_path_iterator_WIND_NON_ZERO = 1
143 enum java_awt_rendering_hints_filter
145 java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
146 java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
147 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
148 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
149 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
153 static int
154 peer_is_disposed(JNIEnv *env, jobject obj)
156 static jfieldID fid = NULL;
157 jclass cls;
158 jobject peer;
160 return 0;
162 if (fid == NULL)
164 cls = (*env)->GetObjectClass(env, obj);
165 fid = (*env)->GetFieldID(env, cls, "component",
166 "Lgnu/java/awt/peer/gtk/GtkComponentPeer;");
168 g_assert(fid != NULL);
169 peer = (*env)->GetObjectField(env, obj, fid);
170 if (peer == NULL || NSA_GET_PTR (env, peer) != NULL)
171 return 0;
172 else
174 return 1;
179 static void
180 grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
182 g_assert (widget != NULL);
183 g_assert (draw != NULL);
184 g_assert (win != NULL);
186 *win = widget->window;
188 *draw = *win;
189 gdk_window_get_internal_paint_info (*win, draw, 0, 0);
190 g_object_ref (*draw);
194 static int
195 x_server_has_render_extension (void)
197 int ev = 0, err = 0;
198 return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
201 static void
202 init_graphics2d_as_pixbuf (struct graphics2d *gr)
204 gint width, height;
205 gint bits_per_sample = 8;
206 gint total_channels = 4;
207 gboolean has_alpha = TRUE;
209 g_assert (gr != NULL);
210 g_assert (gr->drawable != NULL);
212 if (gr->debug) printf ("initializing graphics2d as pixbuf\n");
213 gdk_drawable_get_size (gr->drawable, &width, &height);
214 gr->drawbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
215 has_alpha, bits_per_sample,
216 width, height);
217 g_assert (gr->drawbuf != NULL);
218 g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample);
219 g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels);
221 gr->surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (gr->drawbuf),
222 CAIRO_FORMAT_ARGB32,
223 gdk_pixbuf_get_width (gr->drawbuf),
224 gdk_pixbuf_get_height (gr->drawbuf),
225 gdk_pixbuf_get_rowstride (gr->drawbuf));
226 g_assert (gr->surface != NULL);
227 gr->mode = MODE_DRAWABLE_NO_RENDER;
228 if (gr->cr != NULL)
229 cairo_destroy (gr->cr);
230 gr->cr = cairo_create (gr->surface);
233 static void
234 init_graphics2d_as_renderable (struct graphics2d *gr)
236 Drawable draw;
237 Display * dpy;
238 Visual * vis;
240 g_assert (gr != NULL);
241 g_assert (gr->drawable != NULL);
243 gr->drawbuf = NULL;
245 if (gr->debug) printf ("initializing graphics2d as renderable\n");
246 draw = gdk_x11_drawable_get_xid (gr->drawable);
248 dpy = gdk_x11_drawable_get_xdisplay (gr->drawable);
249 g_assert (dpy != NULL);
251 vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
252 g_assert (vis != NULL);
254 gr->surface = cairo_xlib_surface_create (dpy, draw, vis, gr->width, gr->height);
255 g_assert (gr->surface != NULL);
256 gr->mode = MODE_DRAWABLE_WITH_RENDER;
257 if (gr->cr != NULL)
258 cairo_destroy (gr->cr);
259 gr->cr = cairo_create (gr->surface);
262 static void
263 begin_drawing_operation (JNIEnv *env, struct graphics2d * gr)
265 cairo_status_t cst = cairo_status (gr->cr);
266 if (cst != CAIRO_STATUS_SUCCESS)
268 const char *detail = cairo_status_to_string (cst);
269 JCL_ThrowException (env, "java/lang/InternalError", detail);
270 (*env)->ExceptionDescribe (env);
271 return;
274 switch (gr->mode)
276 case MODE_DRAWABLE_WITH_RENDER:
277 break;
279 case MODE_DRAWABLE_NO_RENDER:
282 gint drawable_width, drawable_height;
283 gint pixbuf_width, pixbuf_height;
284 gint width, height;
286 gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
287 pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
288 pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
289 width = min (drawable_width, pixbuf_width);
290 height = min (drawable_height, pixbuf_height);
292 gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
293 gr->drawable,
294 NULL, /* colormap */
295 0, 0, 0, 0,
296 width, height);
298 if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
299 width, height);
301 break;
303 case MODE_JAVA_ARRAY:
305 jboolean isCopy;
306 gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &isCopy);
307 gr->isCopy |= isCopy;
308 if (gr->isCopy)
310 /* Make sure that the pixel buffer copy is already initalized,
311 i.e. we already failed to get direct access in initState. */
312 g_assert (gr->javabuf_copy != NULL);
313 memcpy (gr->javabuf_copy, gr->javabuf, gr->width * gr->height * 4);
316 break;
320 static void
321 end_drawing_operation (JNIEnv *env, struct graphics2d * gr)
323 cairo_status_t cst = cairo_status (gr->cr);
324 if (cst != CAIRO_STATUS_SUCCESS)
326 /* Report error. */
327 const char *detail = cairo_status_to_string (cst);
328 JCL_ThrowException (env, "java/lang/InternalError", detail);
329 (*env)->ExceptionDescribe (env);
331 /* Recreate cairo status. */
332 cairo_destroy (gr->cr);
333 gr->cr = cairo_create (gr->surface);
334 return;
337 switch (gr->mode)
339 case MODE_DRAWABLE_WITH_RENDER:
340 break;
342 case MODE_DRAWABLE_NO_RENDER:
345 gint drawable_width, drawable_height;
346 gint pixbuf_width, pixbuf_height;
347 gint width, height;
349 gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
350 pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
351 pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
352 width = min (drawable_width, pixbuf_width);
353 height = min (drawable_height, pixbuf_height);
355 gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
356 0, 0, 0, 0,
357 width, height,
358 GDK_RGB_DITHER_NORMAL, 0, 0);
360 if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
361 width, height);
363 break;
365 case MODE_JAVA_ARRAY:
366 if (gr->isCopy)
367 memcpy (gr->javabuf, gr->javabuf_copy, gr->width * gr->height * 4);
368 (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
373 static void
374 update_pattern_transform (struct graphics2d *gr)
376 cairo_matrix_t mat;
378 g_assert (gr != NULL);
379 if (gr->pattern == NULL)
380 return;
382 cairo_get_matrix (gr->cr, &mat);
383 cairo_pattern_set_matrix (gr->pattern, &mat);
386 static void
387 check_for_debug (struct graphics2d *gr)
389 gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL);
392 static void
393 realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject peer)
395 (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(),
396 peer,
397 initComponentGraphics2DUnlockedID);
400 JNIEXPORT void JNICALL
401 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
402 (JNIEnv *env, jobject obj, jobject old)
404 struct graphics2d *g = NULL, *g_old = NULL;
406 gdk_threads_enter();
408 g = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
409 g_assert (g != NULL);
410 memset (g, 0, sizeof(struct graphics2d));
412 g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
413 g_assert (g_old != NULL);
415 if (g_old->debug) printf ("copying state from existing graphics2d\n");
417 g->debug = g_old->debug;
418 g->mode = g_old->mode;
420 g->width = g_old->width;
421 g->height = g_old->height;
423 if (g_old->mode == MODE_JAVA_ARRAY)
425 jint size = g->width * g->height * 4;
427 g->jarray = (*env)->NewGlobalRef (env, g_old->jarray);
428 g->javabuf = (*env)->GetIntArrayElements (env, g->jarray, &g->isCopy);
429 g->isCopy = JNI_TRUE;
430 g->javabuf_copy = (jint *) g_malloc (size);
431 memcpy (g->javabuf_copy, g->javabuf, size);
432 g->surface = cairo_image_surface_create_for_data ((unsigned char *) g->javabuf,
433 CAIRO_FORMAT_ARGB32,
434 g->width,
435 g->height,
436 g->width * 4);
437 g_assert (g->surface != NULL);
438 g->cr = cairo_create (g->surface);
439 g_assert (g->cr != NULL);
440 (*env)->ReleaseIntArrayElements (env, g->jarray, g->javabuf, JNI_ABORT);
442 else
444 g->drawable = g_old->drawable;
445 g_object_ref (g->drawable);
447 if (x_server_has_render_extension ())
448 init_graphics2d_as_renderable (g);
449 else
450 init_graphics2d_as_pixbuf (g);
453 if (g->pattern)
454 cairo_pattern_set_filter (g->pattern, CAIRO_FILTER_FAST);
456 NSA_SET_G2D_PTR (env, obj, g);
458 gdk_threads_leave();
462 JNIEXPORT void JNICALL
463 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III
464 (JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height)
466 struct graphics2d *gr = NULL;
467 jint *cairobuf = NULL;
469 gdk_threads_enter();
471 gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
472 g_assert (gr != NULL);
473 memset (gr, 0, sizeof(struct graphics2d));
475 check_for_debug (gr);
477 if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n",
478 width, height);
480 gr->width = width;
481 gr->height = height;
482 gr->jarray = (*env)->NewGlobalRef(env, jarr);
483 gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &gr->isCopy);
484 if (gr->isCopy)
486 /* We didn't get direct access to the pixel buffer, so we'll have to
487 maintain a separate copy for Cairo. */
488 jint size = gr->width * gr->height * 4;
489 gr->javabuf_copy = (jint *) g_malloc (size);
490 memcpy (gr->javabuf_copy, gr->javabuf, size);
491 cairobuf = gr->javabuf_copy;
493 else
495 /* Have Cairo write directly to the Java array. */
496 cairobuf = gr->javabuf;
498 gr->surface = cairo_image_surface_create_for_data ((unsigned char *) cairobuf,
499 CAIRO_FORMAT_ARGB32,
500 gr->width,
501 gr->height,
502 gr->width * 4);
503 g_assert (gr->surface != NULL);
504 gr->cr = cairo_create (gr->surface);
505 g_assert (gr->cr != NULL);
506 (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
508 gr->mode = MODE_JAVA_ARRAY;
510 if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n",
511 width, height);
513 NSA_SET_G2D_PTR (env, obj, gr);
515 gdk_threads_leave();
518 JNIEXPORT void JNICALL
519 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
520 (JNIEnv *env, jobject obj, jint width, jint height)
522 struct graphics2d *gr = NULL;
524 gdk_threads_enter();
526 gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
527 g_assert (gr != NULL);
528 memset (gr, 0, sizeof(struct graphics2d));
530 check_for_debug (gr);
532 if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
533 width, height);
535 gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
536 gdk_rgb_get_visual ()->depth);
537 g_assert (gr->drawable != NULL);
539 gr->width = width;
540 gr->height = height;
542 if (x_server_has_render_extension ())
543 init_graphics2d_as_renderable (gr);
544 else
545 init_graphics2d_as_pixbuf (gr);
547 if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
548 width, height);
549 NSA_SET_G2D_PTR (env, obj, gr);
551 gdk_threads_leave();
554 JNIEXPORT void JNICALL
555 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
556 (JNIEnv *env, jobject self, jobject other, jint x, jint y)
558 struct graphics2d *src = NULL;
559 struct graphics2d *dst = NULL;
560 gint s_height;
561 gint s_width;
562 gint d_height;
563 gint d_width;
564 gint height;
565 gint width;
566 cairo_matrix_t matrix;
567 cairo_operator_t tmp_op;
569 gdk_threads_enter();
571 if (peer_is_disposed(env, self))
573 gdk_threads_leave();
574 return;
577 src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
578 dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
579 g_assert (src != NULL);
580 g_assert (dst != NULL);
582 if (src->debug) printf ("copying from offscreen drawable\n");
584 begin_drawing_operation(env, dst);
586 /* gdk_flush(); */
588 if (!GDK_IS_DRAWABLE (src->drawable) ||
589 !GDK_IS_DRAWABLE (dst->drawable))
591 gdk_threads_leave ();
592 return;
595 gdk_drawable_get_size (src->drawable, &s_width, &s_height);
596 gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
597 width = min (s_width, d_width);
598 height = min (s_height, d_height);
600 cairo_get_matrix (src->cr, &matrix);
601 cairo_matrix_translate (&matrix, (double)-x, (double)-y);
602 if (src->pattern)
603 cairo_pattern_set_matrix (src->pattern, &matrix);
604 tmp_op = cairo_get_operator (dst->cr);
605 cairo_set_operator(dst->cr, CAIRO_OPERATOR_SOURCE);
606 cairo_set_source_surface (dst->cr, src->surface, 0, 0);
607 cairo_paint (dst->cr);
608 cairo_set_operator(dst->cr, tmp_op);
610 cairo_matrix_translate (&matrix, (double)x, (double)y);
611 if (src->pattern)
612 cairo_pattern_set_matrix (src->pattern, &matrix);
614 gdk_flush();
616 end_drawing_operation(env, dst);
618 if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
620 gdk_threads_leave();
623 JNIEXPORT void JNICALL
624 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStateUnlocked
625 (JNIEnv *env, jobject obj, jobject peer)
627 struct graphics2d *gr = NULL;
628 GtkWidget *widget = NULL;
629 void *ptr = NULL;
631 if (peer_is_disposed(env, obj))
632 return;
634 ptr = NSA_GET_PTR (env, peer);
635 g_assert (ptr != NULL);
637 gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
638 g_assert (gr != NULL);
639 memset (gr, 0, sizeof(struct graphics2d));
641 check_for_debug (gr);
643 widget = GTK_WIDGET (ptr);
644 g_assert (widget != NULL);
646 grab_current_drawable (widget, &(gr->drawable), &(gr->win));
647 g_assert (gr->drawable != NULL);
649 gr->width = widget->allocation.width;
650 gr->height = widget->allocation.height;
652 if (x_server_has_render_extension ())
653 init_graphics2d_as_renderable (gr);
654 else
655 init_graphics2d_as_pixbuf (gr);
657 NSA_SET_G2D_PTR (env, obj, gr);
660 JNIEXPORT void JNICALL
661 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
662 (JNIEnv *env, jobject obj, jobject peer)
664 struct graphics2d *gr = NULL;
665 GtkWidget *widget = NULL;
666 void *ptr = NULL;
668 gdk_threads_enter();
670 if (peer_is_disposed(env, obj))
672 gdk_threads_leave ();
673 return;
676 ptr = NSA_GET_PTR (env, peer);
677 g_assert (ptr != NULL);
679 gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
680 g_assert (gr != NULL);
681 memset (gr, 0, sizeof(struct graphics2d));
683 check_for_debug (gr);
685 widget = GTK_WIDGET (ptr);
686 g_assert (widget != NULL);
688 grab_current_drawable (widget, &(gr->drawable), &(gr->win));
689 g_assert (gr->drawable != NULL);
691 gr->width = widget->allocation.width;
692 gr->height = widget->allocation.height;
694 if (x_server_has_render_extension ())
695 init_graphics2d_as_renderable (gr);
696 else
697 init_graphics2d_as_pixbuf (gr);
699 NSA_SET_G2D_PTR (env, obj, gr);
701 gdk_threads_leave();
704 JNIEXPORT void JNICALL
705 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_connectSignals
706 (JNIEnv *env, jobject obj, jobject peer)
708 void *ptr;
710 gdk_threads_enter ();
712 ptr = NSA_GET_PTR (env, peer);
714 g_signal_connect_after (G_OBJECT (ptr), "realize",
715 G_CALLBACK (realize_cb), obj);
717 gdk_threads_leave ();
720 JNIEXPORT void JNICALL
721 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
722 (JNIEnv *env, jobject obj)
724 struct graphics2d *gr = NULL;
726 gdk_threads_enter();
728 gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
730 if (gr == NULL)
732 gdk_threads_leave();
733 return; /* dispose has been called more than once */
736 if (gr->surface)
737 cairo_surface_destroy (gr->surface);
739 cairo_destroy (gr->cr);
741 if (gr->drawbuf)
742 g_object_unref (gr->drawbuf);
744 if (gr->drawable)
745 g_object_unref (gr->drawable);
747 if (gr->pattern)
748 cairo_pattern_destroy (gr->pattern);
750 if (gr->pattern_surface)
751 cairo_surface_destroy (gr->pattern_surface);
753 if (gr->pattern_pixels)
754 g_free (gr->pattern_pixels);
756 if (gr->mode == MODE_JAVA_ARRAY)
758 (*env)->DeleteGlobalRef (env, gr->jarray);
759 if (gr->javabuf_copy)
760 g_free (gr->javabuf_copy);
763 if (gr->debug) printf ("disposed of graphics2d\n");
765 g_free (gr);
767 gdk_threads_leave();
770 JNIEXPORT void JNICALL
771 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient
772 (JNIEnv *env, jobject obj,
773 jdouble x1, jdouble y1,
774 jdouble x2, jdouble y2,
775 jint r1, jint g1, jint b1, jint a1,
776 jint r2, jint g2, jint b2, jint a2,
777 jboolean cyclic)
779 gdk_threads_enter();
780 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradientUnlocked
781 (env, obj,
782 x1, y1, x2, y2,
783 r1, g1, b1, a1,
784 r2, g2, b2, a2,
785 cyclic);
787 gdk_threads_leave();
790 JNIEXPORT void JNICALL
791 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradientUnlocked
792 (JNIEnv *env, jobject obj,
793 jdouble x1, jdouble y1,
794 jdouble x2, jdouble y2,
795 jint r1, jint g1, jint b1, jint a1,
796 jint r2, jint g2, jint b2, jint a2,
797 jboolean cyclic)
799 struct graphics2d *gr = NULL;
800 cairo_surface_t *surf = NULL;
801 cairo_t *cr2 = NULL;
802 cairo_matrix_t mat;
804 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
805 g_assert (gr != NULL);
807 if (peer_is_disposed(env, obj))
808 return;
810 if (gr->debug)
811 printf ("setGradientUnlocked (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
812 x1, y1,
813 x2, y2,
814 r1, g1, b1, a1,
815 r2, g2, b2, a2);
817 if (cyclic)
818 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2);
819 else
820 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2);
821 g_assert (surf != NULL);
823 cr2 = cairo_create (surf);
825 cairo_identity_matrix (cr2);
827 cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
828 cairo_rectangle (cr2, 0, 0, 1, 2);
829 cairo_fill (cr2);
831 cairo_set_source_rgba (cr2, r2 / 255.0, g2 / 255.0, b2 / 255.0, a2 / 255.0);
832 cairo_rectangle (cr2, 1, 0, 1, 2);
833 cairo_fill (cr2);
835 if (cyclic)
837 cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
838 cairo_rectangle (cr2, 2, 0, 1, 2);
839 cairo_fill (cr2);
842 cairo_matrix_init_identity (&mat);
845 consider the vector [x2 - x1, y2 - y1] = [p,q]
847 this is a line in space starting at an 'origin' x1, y1.
849 it can also be thought of as a "transformed" unit vector in either the
850 x or y directions. we have just *drawn* our gradient as a unit vector
851 (well, a 2-3x unit vector) in the x dimension. so what we want to know
852 is which transformation turns our existing unit vector into [p,q].
854 which means solving for M in
856 [p,q] = M[1,0]
858 [p,q] = |a b| [1,0]
859 |c d|
861 [p,q] = [a,c], with b = d = 0.
863 what does this mean? it means that our gradient is 1-dimensional; as
864 you move through the x axis of our 2 or 3 pixel gradient from logical
865 x positions 0 to 1, the transformation of your x coordinate under the
866 matrix M causes you to accumulate both x and y values in fill
867 space. the y value of a gradient coordinate is ignored, since the
868 gradient is one dimensional. which is correct.
870 unfortunately we want the opposite transformation, it seems, because of
871 the way cairo is going to use this transformation. I'm a bit confused by
872 that, but it seems to work right, so we take reciprocals of values and
873 negate offsets. oh well.
877 double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
878 double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
879 double dx = (x1 == 0.) ? 0. : 1. / x1;
880 double dy = (y1 == 0.) ? 0. : 1. / y1;
881 cairo_pattern_t *p;
883 cairo_matrix_init (&mat,
884 a, 0.,
885 c, 0.,
886 dx, dy);
888 p = cairo_pattern_create_for_surface (surf);
889 cairo_pattern_set_matrix (p, &mat);
890 cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR);
893 /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
894 /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
896 if (gr->pattern)
897 cairo_pattern_destroy (gr->pattern);
899 if (gr->pattern_surface)
900 cairo_surface_destroy (gr->pattern_surface);
902 if (gr->pattern_pixels)
903 g_free (gr->pattern_pixels);
905 gr->pattern_pixels = NULL;
906 gr->pattern_surface = surf;
907 gr->pattern = cairo_pattern_create_for_surface(surf);
909 cairo_set_source (gr->cr, gr->pattern);
912 JNIEXPORT void JNICALL
913 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
914 (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
916 gdk_threads_enter();
918 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixelsUnlocked
919 (env, obj, jarr, w, h, stride);
921 gdk_threads_leave();
924 JNIEXPORT void JNICALL
925 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixelsUnlocked
926 (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
928 struct graphics2d *gr = NULL;
929 jint *jpixels = NULL;
931 if (peer_is_disposed(env, obj))
932 return;
934 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
935 g_assert (gr != NULL);
937 if (gr->debug)
938 printf ("setTexturePixelsUnlocked (%d pixels, %dx%d, stride: %d)\n",
939 (*env)->GetArrayLength (env, jarr), w, h, stride);
941 if (gr->pattern)
942 cairo_pattern_destroy (gr->pattern);
944 if (gr->pattern_surface)
945 cairo_surface_destroy (gr->pattern_surface);
947 if (gr->pattern_pixels)
948 g_free (gr->pattern_pixels);
950 gr->pattern = NULL;
951 gr->pattern_surface = NULL;
952 gr->pattern_pixels = NULL;
954 gr->pattern_pixels = (char *) g_malloc (h * stride * 4);
955 g_assert (gr->pattern_pixels != NULL);
957 jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
958 g_assert (jpixels != NULL);
959 memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
960 (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
962 gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels,
963 CAIRO_FORMAT_ARGB32,
964 w, h, stride * 4);
965 g_assert (gr->pattern_surface != NULL);
966 gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
967 g_assert (gr->pattern != NULL);
968 cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT);
969 cairo_set_source (gr->cr, gr->pattern);
972 JNIEXPORT void JNICALL
973 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
974 (JNIEnv *env, jobject obj, jintArray java_pixels,
975 jint w, jint h, jint stride, jdoubleArray java_matrix)
977 struct graphics2d *gr = NULL;
978 jint *native_pixels = NULL;
979 jdouble *native_matrix = NULL;
981 gdk_threads_enter();
983 if (peer_is_disposed(env, obj))
985 gdk_threads_leave();
986 return;
989 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
990 g_assert (gr != NULL);
992 if (gr->debug)
993 printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
994 (*env)->GetArrayLength (env, java_pixels), w, h, stride);
996 native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
997 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
998 g_assert (native_pixels != NULL);
999 g_assert (native_matrix != NULL);
1000 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
1002 begin_drawing_operation (env, gr);
1005 cairo_matrix_t mat;
1006 cairo_pattern_t *p;
1007 cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels,
1008 CAIRO_FORMAT_ARGB32,
1009 w, h, stride * 4);
1010 cairo_matrix_init_identity (&mat);
1011 cairo_matrix_init (&mat,
1012 native_matrix[0], native_matrix[1],
1013 native_matrix[2], native_matrix[3],
1014 native_matrix[4], native_matrix[5]);
1016 p = cairo_pattern_create_for_surface (surf);
1017 cairo_pattern_set_matrix (p, &mat);
1018 if (gr->pattern)
1019 cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern));
1020 cairo_set_source (gr->cr, p);
1021 cairo_paint (gr->cr);
1022 cairo_pattern_destroy (p);
1023 cairo_surface_destroy (surf);
1026 end_drawing_operation (env, gr);
1028 (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
1029 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
1031 gdk_threads_leave();
1034 /* passthrough methods to cairo */
1036 JNIEXPORT void JNICALL
1037 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave
1038 (JNIEnv *env, jobject obj)
1040 struct graphics2d *gr = NULL;
1042 gdk_threads_enter();
1044 if (peer_is_disposed(env, obj))
1046 gdk_threads_leave();
1047 return;
1050 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1051 g_assert (gr != NULL);
1052 if (gr->debug) printf ("cairo_save\n");
1053 cairo_save (gr->cr);
1055 gdk_threads_leave();
1058 JNIEXPORT void JNICALL
1059 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
1060 (JNIEnv *env, jobject obj)
1062 struct graphics2d *gr = NULL;
1064 gdk_threads_enter();
1066 if (peer_is_disposed(env, obj))
1068 gdk_threads_leave();
1069 return;
1072 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1073 g_assert (gr != NULL);
1074 if (gr->debug) printf ("cairo_restore\n");
1075 cairo_restore (gr->cr);
1076 update_pattern_transform (gr);
1078 gdk_threads_leave();
1081 JNIEXPORT void JNICALL
1082 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
1083 (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
1085 gdk_threads_enter();
1087 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrixUnlocked
1088 (env, obj, java_matrix);
1090 gdk_threads_leave();
1093 JNIEXPORT void JNICALL
1094 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrixUnlocked
1095 (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
1097 struct graphics2d *gr = NULL;
1098 jdouble *native_matrix = NULL;
1100 if (peer_is_disposed(env, obj))
1101 return;
1103 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1105 /* cairoSetMatrix was called before this graphics object's component
1106 was realized. */
1107 if (gr == NULL)
1108 return;
1110 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
1111 g_assert (native_matrix != NULL);
1112 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
1114 if (gr->debug)
1115 printf ("cairo_matrix_init [ %f, %f, %f, %f, %f, %f ]\n",
1116 native_matrix[0], native_matrix[1],
1117 native_matrix[2], native_matrix[3],
1118 native_matrix[4], native_matrix[5]);
1121 cairo_matrix_t mat;
1123 cairo_matrix_init_identity (&mat);
1124 cairo_matrix_init (&mat,
1125 native_matrix[0], native_matrix[1],
1126 native_matrix[2], native_matrix[3],
1127 native_matrix[4], native_matrix[5]);
1128 cairo_set_matrix (gr->cr, &mat);
1131 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
1132 update_pattern_transform (gr);
1135 static void
1136 install_font_peer(cairo_t *cr,
1137 struct peerfont *pfont,
1138 int debug)
1140 cairo_font_face_t *ft;
1141 FT_Face face = NULL;
1143 g_assert(cr != NULL);
1144 g_assert(pfont != NULL);
1146 if (pfont->graphics_resource == NULL)
1148 face = pango_ft2_font_get_face (pfont->font);
1149 g_assert (face != NULL);
1151 ft = cairo_ft_font_face_create_for_ft_face (face, 0);
1152 g_assert (ft != NULL);
1154 if (debug) printf ("install_font_peer made new cairo font for '%s' at %f\n",
1155 face->family_name,
1156 (pango_font_description_get_size (pfont->desc) /
1157 (double)PANGO_SCALE));
1159 cairo_set_font_face (cr, ft);
1160 cairo_font_face_destroy (ft);
1161 cairo_set_font_size (cr,
1162 (pango_font_description_get_size (pfont->desc) /
1163 (double)PANGO_SCALE));
1164 ft = cairo_get_font_face (cr);
1165 pfont->graphics_resource = ft;
1167 else
1169 if (debug) printf ("install_font_peer reused existing font resource\n");
1170 ft = (cairo_font_face_t *) pfont->graphics_resource;
1171 cairo_set_font_face (cr, ft);
1176 JNIEXPORT void JNICALL
1177 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
1178 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font)
1180 struct peerfont *pfont = NULL;
1182 gdk_threads_enter();
1184 g_assert(java_font != NULL);
1186 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
1187 g_assert (pfont != NULL);
1188 if (pfont->graphics_resource != NULL)
1190 cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
1191 pfont->graphics_resource = NULL;
1194 gdk_threads_leave();
1197 static void
1198 paint_glyph_run(JNIEnv *env,
1199 struct graphics2d *gr,
1200 cairo_glyph_t **glyphs,
1201 gint *n_glyphs,
1202 PangoLayoutRun *run)
1204 gint i = 0;
1205 gint x = 0, y = 0;
1207 g_assert (gr != NULL);
1208 g_assert (glyphs != NULL);
1209 g_assert (n_glyphs != NULL);
1210 g_assert (run != NULL);
1212 if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
1214 if (*n_glyphs < run->glyphs->num_glyphs)
1216 *glyphs = g_realloc(*glyphs,
1217 (sizeof(cairo_glyph_t)
1218 * run->glyphs->num_glyphs));
1219 *n_glyphs = run->glyphs->num_glyphs;
1222 g_assert (*glyphs != NULL);
1224 if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs);
1226 for (i = 0; i < run->glyphs->num_glyphs; ++i)
1228 (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
1230 (*glyphs)[i].x =
1231 ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
1232 / ((double) PANGO_SCALE);
1234 (*glyphs)[i].y =
1235 ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
1236 / ((double) PANGO_SCALE);
1238 if (gr->debug) printf(" (%ld @ %f,%f)",
1239 (*glyphs)[i].index,
1240 (*glyphs)[i].x,
1241 (*glyphs)[i].y);
1243 x += run->glyphs->glyphs[i].geometry.width;
1246 if (gr->debug) printf("\n");
1247 begin_drawing_operation (env, gr);
1248 cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs);
1249 end_drawing_operation (env, gr);
1254 JNIEXPORT void JNICALL
1255 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGlyphVector
1256 (JNIEnv *env, jobject self,
1257 jobject font,
1258 jfloat x, jfloat y, jint n,
1259 jintArray java_codes,
1260 jfloatArray java_positions)
1263 struct graphics2d *gr = NULL;
1264 struct peerfont *pfont = NULL;
1265 cairo_glyph_t *glyphs = NULL;
1266 int *native_codes;
1267 float *native_positions;
1268 jint i = 0;
1270 gdk_threads_enter ();
1272 g_assert (self != NULL);
1273 g_assert (java_codes != NULL);
1274 g_assert (java_positions != NULL);
1276 if (peer_is_disposed(env, self))
1278 gdk_threads_leave();
1279 return;
1282 gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
1283 g_assert (gr != NULL);
1285 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
1286 g_assert (pfont != NULL);
1288 install_font_peer(gr->cr, pfont, gr->debug);
1290 glyphs = g_malloc( sizeof(cairo_glyph_t) * n);
1291 g_assert (glyphs != NULL);
1293 native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
1294 native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL);
1296 for (i = 0; i < n; ++i)
1298 glyphs[i].index = native_codes[i];
1299 glyphs[i].x = x + native_positions[ 2*i ];
1300 glyphs[i].y = y + native_positions[ 2*i + 1];
1303 (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0);
1304 (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
1306 begin_drawing_operation (env, gr);
1307 cairo_show_glyphs (gr->cr, glyphs, n);
1308 end_drawing_operation (env, gr);
1310 g_free(glyphs);
1312 gdk_threads_leave ();
1315 JNIEXPORT void JNICALL
1316 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout
1317 (JNIEnv *env, jobject self, jobject java_layout, jfloat x, jfloat y)
1320 * FIXME: Some day we expect either cairo or pango will know how to make
1321 * a pango layout paint to a cairo surface. that day is not yet here.
1324 struct graphics2d *gr = NULL;
1325 struct textlayout *tl = NULL;
1326 PangoLayoutIter *i = NULL;
1327 PangoLayoutRun *run = NULL;
1328 cairo_glyph_t *glyphs = NULL;
1329 gint n_glyphs = 0;
1331 gdk_threads_enter ();
1333 g_assert (self != NULL);
1334 g_assert (java_layout != NULL);
1336 gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
1337 tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout);
1339 g_assert (gr != NULL);
1340 g_assert (tl != NULL);
1341 g_assert (tl->pango_layout != NULL);
1343 if (gr->debug) printf ("painting pango layout\n");
1345 if (peer_is_disposed(env, self))
1347 gdk_threads_leave();
1348 return;
1351 i = pango_layout_get_iter (tl->pango_layout);
1352 g_assert (i != NULL);
1354 cairo_translate (gr->cr, x, y);
1358 run = pango_layout_iter_get_run (i);
1359 if (run != NULL)
1360 paint_glyph_run (env, gr, &glyphs, &n_glyphs, run);
1362 while (pango_layout_iter_next_run (i));
1364 if (glyphs != NULL)
1365 g_free (glyphs);
1367 cairo_translate (gr->cr, -x, -y);
1369 pango_layout_iter_free (i);
1371 gdk_threads_leave ();
1374 JNIEXPORT void JNICALL
1375 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
1376 (JNIEnv *env, jobject obj, jint op)
1378 struct graphics2d *gr = NULL;
1380 gdk_threads_enter();
1382 if (peer_is_disposed(env, obj))
1384 gdk_threads_leave();
1385 return;
1388 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1389 g_assert (gr != NULL);
1390 if (gr->debug) printf ("cairo_set_operator %d\n", op);
1391 switch ((enum java_awt_alpha_composite_rule) op)
1393 case java_awt_alpha_composite_CLEAR:
1394 cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
1395 break;
1397 case java_awt_alpha_composite_SRC:
1398 cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE);
1399 break;
1401 case java_awt_alpha_composite_SRC_OVER:
1402 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
1403 break;
1405 case java_awt_alpha_composite_DST_OVER:
1406 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER);
1407 break;
1409 case java_awt_alpha_composite_SRC_IN:
1410 cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
1411 break;
1413 case java_awt_alpha_composite_DST_IN:
1414 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN);
1415 break;
1417 case java_awt_alpha_composite_SRC_OUT:
1418 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
1419 break;
1421 case java_awt_alpha_composite_DST_OUT:
1422 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT);
1423 break;
1425 case java_awt_alpha_composite_DST:
1426 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST);
1427 break;
1429 case java_awt_alpha_composite_SRC_ATOP:
1430 cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
1431 break;
1433 case java_awt_alpha_composite_DST_ATOP:
1434 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP);
1435 break;
1437 case java_awt_alpha_composite_XOR:
1438 cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
1439 break;
1442 gdk_threads_leave();
1445 JNIEXPORT void JNICALL
1446 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColor
1447 (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a)
1449 gdk_threads_enter();
1451 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColorUnlocked
1452 (env, obj, r, g, b, a);
1454 gdk_threads_leave();
1457 JNIEXPORT void JNICALL
1458 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColorUnlocked
1459 (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a)
1461 struct graphics2d *gr = NULL;
1463 if (peer_is_disposed(env, obj))
1464 return;
1466 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1467 g_assert (gr != NULL);
1469 /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider
1470 colors in opposite pixel order. I have no idea why. thus when you
1471 draw to a PixBuf, you must exchange the R and B components of your
1472 color. */
1474 if (gr->debug)
1475 printf ("cairo_set_source_rgba (%f, %f, %f, %f)\n", r, g, b, a);
1477 if (gr->drawbuf)
1478 cairo_set_source_rgba (gr->cr, b, g, r, a);
1479 else
1480 cairo_set_source_rgba (gr->cr, r, g, b, a);
1483 JNIEXPORT void JNICALL
1484 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule
1485 (JNIEnv *env, jobject obj, jint rule)
1487 struct graphics2d *gr = NULL;
1489 gdk_threads_enter();
1491 if (peer_is_disposed(env, obj))
1493 gdk_threads_leave();
1494 return;
1497 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1498 if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
1499 g_assert (gr != NULL);
1500 switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
1502 case java_awt_geom_path_iterator_WIND_NON_ZERO:
1503 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
1504 break;
1505 case java_awt_geom_path_iterator_WIND_EVEN_ODD:
1506 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
1507 break;
1510 gdk_threads_leave();
1513 JNIEXPORT void JNICALL
1514 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth
1515 (JNIEnv *env, jobject obj, jdouble width)
1517 gdk_threads_enter();
1519 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidthUnlocked
1520 (env, obj, width);
1522 gdk_threads_leave();
1525 JNIEXPORT void JNICALL
1526 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidthUnlocked
1527 (JNIEnv *env, jobject obj, jdouble width)
1529 struct graphics2d *gr = NULL;
1531 if (peer_is_disposed(env, obj))
1532 return;
1534 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1535 g_assert (gr != NULL);
1536 if (gr->debug) printf ("cairo_set_line_width %f\n", width);
1537 cairo_set_line_width (gr->cr, width);
1540 JNIEXPORT void JNICALL
1541 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap
1542 (JNIEnv *env, jobject obj, jint cap)
1544 gdk_threads_enter();
1546 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCapUnlocked
1547 (env, obj, cap);
1549 gdk_threads_leave();
1552 JNIEXPORT void JNICALL
1553 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCapUnlocked
1554 (JNIEnv *env, jobject obj, jint cap)
1556 struct graphics2d *gr = NULL;
1558 if (peer_is_disposed(env, obj))
1559 return;
1561 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1562 g_assert (gr != NULL);
1563 if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
1564 switch ((enum java_awt_basic_stroke_cap_rule) cap)
1566 case java_awt_basic_stroke_CAP_BUTT:
1567 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
1568 break;
1570 case java_awt_basic_stroke_CAP_ROUND:
1571 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
1572 break;
1574 case java_awt_basic_stroke_CAP_SQUARE:
1575 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
1576 break;
1580 JNIEXPORT void JNICALL
1581 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin
1582 (JNIEnv *env, jobject obj, jint join)
1584 gdk_threads_enter();
1586 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoinUnlocked
1587 (env, obj, join);
1589 gdk_threads_leave();
1592 JNIEXPORT void JNICALL
1593 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoinUnlocked
1594 (JNIEnv *env, jobject obj, jint join)
1596 struct graphics2d *gr = NULL;
1598 if (peer_is_disposed(env, obj))
1599 return;
1601 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1602 g_assert (gr != NULL);
1603 if (gr->debug) printf ("cairo_set_line_join %d\n", join);
1604 switch ((enum java_awt_basic_stroke_join_rule) join)
1606 case java_awt_basic_stroke_JOIN_MITER:
1607 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
1608 break;
1610 case java_awt_basic_stroke_JOIN_ROUND:
1611 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
1612 break;
1614 case java_awt_basic_stroke_JOIN_BEVEL:
1615 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
1616 break;
1620 JNIEXPORT void JNICALL
1621 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash
1622 (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
1624 gdk_threads_enter();
1626 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDashUnlocked
1627 (env, obj, dashes, ndash, offset);
1629 gdk_threads_leave();
1632 JNIEXPORT void JNICALL
1633 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDashUnlocked
1634 (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
1636 struct graphics2d *gr = NULL;
1637 jdouble *dasharr = NULL;
1639 if (peer_is_disposed(env, obj))
1640 return;
1642 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1643 g_assert (gr != NULL);
1644 if (gr->debug) printf ("cairo_set_dash\n");
1645 dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
1646 g_assert (dasharr != NULL);
1647 cairo_set_dash (gr->cr, dasharr, ndash, offset);
1648 (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
1651 JNIEXPORT void JNICALL
1652 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit
1653 (JNIEnv *env, jobject obj, jdouble miter)
1655 gdk_threads_enter();
1657 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimitUnlocked
1658 (env, obj, miter);
1660 gdk_threads_leave();
1663 JNIEXPORT void JNICALL
1664 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimitUnlocked
1665 (JNIEnv *env, jobject obj, jdouble miter)
1667 struct graphics2d *gr = NULL;
1669 if (peer_is_disposed(env, obj))
1670 return;
1672 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1673 g_assert (gr != NULL);
1674 if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
1675 cairo_set_miter_limit (gr->cr, miter);
1678 JNIEXPORT void JNICALL
1679 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath
1680 (JNIEnv *env, jobject obj)
1682 struct graphics2d *gr = NULL;
1684 gdk_threads_enter();
1686 if (peer_is_disposed(env, obj))
1688 gdk_threads_leave();
1689 return;
1692 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1694 if (gr == NULL)
1696 gdk_threads_leave ();
1697 return;
1700 if (gr->debug) printf ("cairo_new_path\n");
1701 cairo_new_path (gr->cr);
1703 gdk_threads_leave();
1706 JNIEXPORT void JNICALL
1707 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo
1708 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
1710 struct graphics2d *gr = NULL;
1712 gdk_threads_enter();
1714 if (peer_is_disposed(env, obj))
1716 gdk_threads_leave();
1717 return;
1720 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1721 g_assert (gr != NULL);
1722 if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y);
1723 cairo_move_to (gr->cr, x, y);
1725 gdk_threads_leave();
1728 JNIEXPORT void JNICALL
1729 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo
1730 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
1732 struct graphics2d *gr = NULL;
1734 gdk_threads_enter();
1736 if (peer_is_disposed(env, obj))
1738 gdk_threads_leave();
1739 return;
1742 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1743 g_assert (gr != NULL);
1744 if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y);
1745 cairo_line_to (gr->cr, x, y);
1747 gdk_threads_leave();
1750 JNIEXPORT void JNICALL
1751 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo
1752 (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
1754 struct graphics2d *gr = NULL;
1756 gdk_threads_enter();
1758 if (peer_is_disposed(env, obj))
1760 gdk_threads_leave();
1761 return;
1764 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1765 g_assert (gr != NULL);
1766 if (gr->debug)
1767 printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n",
1768 x1, y1, x2, y2, x3, y3);
1769 cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
1771 gdk_threads_leave();
1774 JNIEXPORT void JNICALL
1775 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo
1776 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1778 struct graphics2d *gr = NULL;
1780 gdk_threads_enter();
1782 if (peer_is_disposed(env, obj))
1784 gdk_threads_leave();
1785 return;
1788 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1789 g_assert (gr != NULL);
1790 if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
1791 cairo_rel_move_to (gr->cr, dx, dy);
1793 gdk_threads_leave();
1796 JNIEXPORT void JNICALL
1797 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo
1798 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1800 struct graphics2d *gr = NULL;
1802 gdk_threads_enter();
1804 if (peer_is_disposed(env, obj))
1806 gdk_threads_leave();
1807 return;
1810 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1811 g_assert (gr != NULL);
1812 if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
1813 cairo_rel_line_to (gr->cr, dx, dy);
1815 gdk_threads_leave();
1818 JNIEXPORT void JNICALL
1819 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo
1820 (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
1822 struct graphics2d *gr = NULL;
1824 gdk_threads_enter();
1826 if (peer_is_disposed(env, obj))
1828 gdk_threads_leave();
1829 return;
1832 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1833 g_assert (gr != NULL);
1834 if (gr->debug)
1835 printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n",
1836 dx1, dy1, dx2, dy2, dx3, dy3);
1837 cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
1839 gdk_threads_leave();
1842 JNIEXPORT void JNICALL
1843 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle
1844 (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
1846 struct graphics2d *gr = NULL;
1848 gdk_threads_enter();
1850 if (peer_is_disposed(env, obj))
1852 gdk_threads_leave();
1853 return;
1856 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1858 if (gr == NULL)
1860 gdk_threads_leave ();
1861 return;
1864 if (gr->debug)
1865 printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
1866 cairo_rectangle (gr->cr, x, y, width, height);
1868 gdk_threads_leave();
1871 JNIEXPORT void JNICALL
1872 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath
1873 (JNIEnv *env, jobject obj)
1875 struct graphics2d *gr = NULL;
1877 gdk_threads_enter();
1879 if (peer_is_disposed(env, obj))
1881 gdk_threads_leave();
1882 return;
1885 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1886 g_assert (gr != NULL);
1887 if (gr->debug) printf ("cairo_close_path\n");
1888 cairo_close_path (gr->cr);
1890 gdk_threads_leave();
1893 JNIEXPORT void JNICALL
1894 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
1895 (JNIEnv *env, jobject obj)
1897 struct graphics2d *gr = NULL;
1899 gdk_threads_enter();
1901 if (peer_is_disposed(env, obj))
1903 gdk_threads_leave();
1904 return;
1907 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1908 g_assert (gr != NULL);
1909 if (gr->debug) printf ("cairo_stroke\n");
1910 begin_drawing_operation (env, gr);
1911 cairo_stroke (gr->cr);
1912 end_drawing_operation (env, gr);
1914 gdk_threads_leave();
1917 JNIEXPORT void JNICALL
1918 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
1919 (JNIEnv *env, jobject obj)
1921 struct graphics2d *gr = NULL;
1923 gdk_threads_enter();
1925 if (peer_is_disposed(env, obj))
1927 gdk_threads_leave();
1928 return;
1931 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1932 g_assert (gr != NULL);
1933 if (gr->debug) printf ("cairo_fill\n");
1934 begin_drawing_operation (env, gr);
1935 cairo_fill (gr->cr);
1936 end_drawing_operation (env, gr);
1938 gdk_threads_leave();
1941 JNIEXPORT void JNICALL
1942 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
1943 (JNIEnv *env, jobject obj)
1945 struct graphics2d *gr = NULL;
1947 gdk_threads_enter();
1949 if (peer_is_disposed(env, obj))
1951 gdk_threads_leave();
1952 return;
1955 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1957 if (gr == NULL)
1959 gdk_threads_leave ();
1960 return;
1963 if (gr->debug) printf ("cairo_clip\n");
1964 begin_drawing_operation (env, gr);
1965 cairo_reset_clip (gr->cr);
1966 cairo_clip (gr->cr);
1967 end_drawing_operation (env, gr);
1969 gdk_threads_leave();
1972 JNIEXPORT void JNICALL
1973 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
1974 (JNIEnv *env, jobject obj, jint filter)
1976 gdk_threads_enter();
1978 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilterUnlocked
1979 (env, obj, filter);
1981 gdk_threads_leave();
1984 JNIEXPORT void JNICALL
1985 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilterUnlocked
1986 (JNIEnv *env, jobject obj, jint filter)
1988 struct graphics2d *gr = NULL;
1990 if (peer_is_disposed(env, obj))
1991 return;
1993 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1994 g_assert (gr != NULL);
1995 if (gr->debug) printf ("cairo_pattern_set_filter %d\n", filter);
1996 switch ((enum java_awt_rendering_hints_filter) filter)
1998 case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
1999 cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
2000 break;
2001 case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
2002 cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR);
2003 break;
2004 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
2005 cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST);
2006 break;
2007 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
2008 cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
2009 break;
2010 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
2011 cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST);
2012 break;