1 /* gnu_java_awt_peer_gtk_GdkGraphics2d.c
2 Copyright (C) 2003, 2004 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)
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., 59 Temple Place, Suite 330, Boston, MA
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
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 "gtkcairopeer.h"
40 #include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
41 #include <gdk/gdktypes.h>
42 #include <gdk/gdkprivate.h>
45 #include <gdk-pixbuf/gdk-pixbuf.h>
46 #include <gdk-pixbuf/gdk-pixdata.h>
53 struct state_table *native_graphics2d_state_table;
55 #define NSA_G2D_INIT(env, clazz) \
56 native_graphics2d_state_table = init_state_table (env, clazz)
58 #define NSA_GET_G2D_PTR(env, obj) \
59 get_state (env, obj, native_graphics2d_state_table)
61 #define NSA_SET_G2D_PTR(env, obj, ptr) \
62 set_state (env, obj, native_graphics2d_state_table, (void *)ptr)
64 #define NSA_DEL_G2D_PTR(env, obj) \
65 remove_state_slot (env, obj, native_graphics2d_state_table)
67 JNIEXPORT void JNICALL
68 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState
69 (JNIEnv *env, jclass clazz)
72 NSA_G2D_INIT (env, clazz);
76 /* these public final constants are part of the java2d public API, so we
77 write them explicitly here to save fetching them from the constant pool
81 #define min(x,y) ((x) < (y) ? (x) : (y))
84 enum java_awt_alpha_composite_rule
86 java_awt_alpha_composite_CLEAR = 1,
87 java_awt_alpha_composite_SRC = 2,
88 java_awt_alpha_composite_SRC_OVER = 3,
89 java_awt_alpha_composite_DST_OVER = 4,
90 java_awt_alpha_composite_SRC_IN = 5,
91 java_awt_alpha_composite_DST_IN = 6,
92 java_awt_alpha_composite_SRC_OUT = 7,
93 java_awt_alpha_composite_DST_OUT = 8,
94 java_awt_alpha_composite_DST = 9,
95 java_awt_alpha_composite_SRC_ATOP = 10,
96 java_awt_alpha_composite_DST_ATOP = 11,
97 java_awt_alpha_composite_XOR = 12
100 enum java_awt_basic_stroke_join_rule
102 java_awt_basic_stroke_JOIN_MITER = 0,
103 java_awt_basic_stroke_JOIN_ROUND = 1,
104 java_awt_basic_stroke_JOIN_BEVEL = 2
107 enum java_awt_basic_stroke_cap_rule
109 java_awt_basic_stroke_CAP_BUTT = 0,
110 java_awt_basic_stroke_CAP_ROUND = 1,
111 java_awt_basic_stroke_CAP_SQUARE = 2
114 enum java_awt_geom_path_iterator_winding_rule
116 java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
117 java_awt_geom_path_iterator_WIND_NON_ZERO = 1
120 enum java_awt_rendering_hints_filter
122 java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
123 java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
124 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
125 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
126 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
131 peer_is_disposed(JNIEnv *env, jobject obj)
133 static jfieldID fid = NULL;
141 cls = (*env)->GetObjectClass(env, obj);
142 fid = (*env)->GetFieldID(env, cls, "component",
143 "Lgnu/java/awt/peer/gtk/GtkComponentPeer;");
145 g_assert(fid != NULL);
146 peer = (*env)->GetObjectField(env, obj, fid);
147 if (peer == NULL || NSA_GET_PTR (env, peer) != NULL)
157 grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
159 g_assert (widget != NULL);
160 g_assert (draw != NULL);
161 g_assert (win != NULL);
163 *win = widget->window;
166 gdk_window_get_internal_paint_info (*win, draw, 0, 0);
167 g_object_ref (*draw);
172 x_server_has_render_extension (void)
175 return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
180 init_graphics2d_as_pixbuf (struct graphics2d *gr)
183 gint bits_per_sample = 8;
184 gint total_channels = 4;
185 gboolean has_alpha = TRUE;
187 g_assert (gr != NULL);
188 g_assert (gr->drawable != NULL);
190 if (gr->debug) printf ("initializing graphics2d as pixbuf\n");
191 gdk_drawable_get_size (gr->drawable, &width, &height);
192 gr->drawbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
193 has_alpha, bits_per_sample,
195 g_assert (gr->drawbuf != NULL);
196 g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample);
197 g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels);
199 gr->surface = cairo_surface_create_for_image (gdk_pixbuf_get_pixels (gr->drawbuf),
201 gdk_pixbuf_get_width (gr->drawbuf),
202 gdk_pixbuf_get_height (gr->drawbuf),
203 gdk_pixbuf_get_rowstride (gr->drawbuf));
204 g_assert (gr->surface != NULL);
205 g_assert (gr->cr != NULL);
206 cairo_set_target_surface (gr->cr, gr->surface);
210 init_graphics2d_as_renderable (struct graphics2d *gr)
216 g_assert (gr != NULL);
217 g_assert (gr->drawable != NULL);
221 if (gr->debug) printf ("initializing graphics2d as renderable\n");
222 draw = gdk_x11_drawable_get_xid (gr->drawable);
224 dpy = gdk_x11_drawable_get_xdisplay (gr->drawable);
225 g_assert (dpy != NULL);
227 vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
228 g_assert (vis != NULL);
230 gr->surface = cairo_xlib_surface_create (dpy, draw, vis,
232 DefaultColormap (dpy, DefaultScreen (dpy)));
233 g_assert (gr->surface != NULL);
234 g_assert (gr->cr != NULL);
235 cairo_set_target_surface (gr->cr, gr->surface);
239 begin_drawing_operation (struct graphics2d * gr)
241 g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
245 gint drawable_width, drawable_height;
246 gint pixbuf_width, pixbuf_height;
249 gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
250 pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
251 pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
252 width = min (drawable_width, pixbuf_width);
253 height = min (drawable_height, pixbuf_height);
255 gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
261 if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
267 end_drawing_operation (struct graphics2d * gr)
269 g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
272 gint drawable_width, drawable_height;
273 gint pixbuf_width, pixbuf_height;
276 gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
277 pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
278 pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
279 width = min (drawable_width, pixbuf_width);
280 height = min (drawable_height, pixbuf_height);
282 gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
285 GDK_RGB_DITHER_NORMAL, 0, 0);
287 if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
294 update_pattern_transform (struct graphics2d *gr)
296 double a, b, c, d, tx, ty;
297 cairo_matrix_t *mat = NULL;
299 g_assert (gr != NULL);
300 if (gr->pattern == NULL)
304 /* temporarily disabled: ambiguous behavior */
305 /* cairo_get_matrix (gr->cr, &a, &b, &c, &d, &tx, &ty); */
306 mat = cairo_matrix_create ();
307 g_assert (mat != NULL);
308 cairo_matrix_set_affine (mat, a, b, c, d, tx, ty);
309 cairo_pattern_set_matrix (gr->pattern, mat);
310 cairo_matrix_destroy (mat);
314 check_for_debug (struct graphics2d *gr)
316 gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL);
320 realize_cb (GtkWidget *widget, jobject peer)
322 gdk_threads_leave ();
324 (*gdk_env)->CallVoidMethod (gdk_env, peer, initComponentGraphics2DID);
326 gdk_threads_enter ();
329 JNIEXPORT void JNICALL
330 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
331 (JNIEnv *env, jobject obj, jobject old)
333 struct graphics2d *g = NULL, *g_old = NULL;
336 g = (struct graphics2d *) malloc (sizeof (struct graphics2d));
337 g_assert (g != NULL);
338 memset (g, 0, sizeof(struct graphics2d));
340 g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
341 g_assert (g_old != NULL);
343 if (g_old->debug) printf ("copying state from existing graphics2d\n");
345 g->drawable = g_old->drawable;
346 g->debug = g_old->debug;
348 g_object_ref (g->drawable);
350 g->cr = cairo_create();
351 g_assert (g->cr != NULL);
353 if (x_server_has_render_extension ())
354 init_graphics2d_as_renderable (g);
356 init_graphics2d_as_pixbuf (g);
358 cairo_surface_set_filter (g->surface, CAIRO_FILTER_FAST);
360 NSA_SET_G2D_PTR (env, obj, g);
365 JNIEXPORT void JNICALL
366 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
367 (JNIEnv *env, jobject obj, jint width, jint height)
369 struct graphics2d *gr;
372 gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
373 g_assert (gr != NULL);
374 memset (gr, 0, sizeof(struct graphics2d));
376 check_for_debug (gr);
378 if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
381 gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
382 gdk_rgb_get_visual ()->depth);
383 g_assert (gr->drawable != NULL);
385 gr->cr = cairo_create();
386 g_assert (gr->cr != NULL);
388 if (x_server_has_render_extension ())
389 init_graphics2d_as_renderable (gr);
391 init_graphics2d_as_pixbuf (gr);
393 if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
395 NSA_SET_G2D_PTR (env, obj, gr);
399 JNIEXPORT void JNICALL
400 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
401 (JNIEnv *env, jobject self, jobject other, jint x, jint y)
403 struct graphics2d *src = NULL, *dst = NULL;
404 gint s_height, s_width, d_height, d_width, height, width;
405 cairo_matrix_t *matrix;
406 cairo_operator_t tmp_op;
409 if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; }
410 src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
411 dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
412 g_assert (src != NULL);
413 g_assert (dst != NULL);
415 if (src->debug) printf ("copying from offscreen drawable\n");
417 begin_drawing_operation(dst);
421 gdk_drawable_get_size (src->drawable, &s_width, &s_height);
422 gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
423 width = min (s_width, d_width);
424 height = min (s_height, d_height);
426 matrix = cairo_matrix_create ();
427 cairo_surface_get_matrix (src->surface, matrix);
428 cairo_matrix_translate (matrix, (double)-x, (double)-y);
429 cairo_surface_set_matrix (src->surface, matrix);
431 tmp_op = cairo_current_operator (dst->cr);
432 cairo_set_operator(dst->cr, CAIRO_OPERATOR_SRC);
433 cairo_show_surface (dst->cr, src->surface, width, height);
434 cairo_set_operator(dst->cr, tmp_op);
436 cairo_matrix_translate (matrix, (double)x, (double)y);
437 cairo_surface_set_matrix (src->surface, matrix);
438 cairo_matrix_destroy (matrix);
442 end_drawing_operation(dst);
444 if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
448 JNIEXPORT void JNICALL
449 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
450 (JNIEnv *env, jobject obj, jobject peer)
452 struct graphics2d *gr = NULL;
453 GtkWidget *widget = NULL;
457 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
458 ptr = NSA_GET_PTR (env, peer);
459 g_assert (ptr != NULL);
461 gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
462 g_assert (gr != NULL);
463 memset (gr, 0, sizeof(struct graphics2d));
465 check_for_debug (gr);
467 gr->cr = cairo_create();
468 g_assert (gr->cr != NULL);
470 widget = GTK_WIDGET (ptr);
471 g_assert (widget != NULL);
473 grab_current_drawable (widget, &(gr->drawable), &(gr->win));
474 g_assert (gr->drawable != NULL);
476 if (x_server_has_render_extension ())
477 init_graphics2d_as_renderable (gr);
479 init_graphics2d_as_pixbuf (gr);
481 NSA_SET_G2D_PTR (env, obj, gr);
485 JNIEXPORT void JNICALL
486 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_connectSignals
487 (JNIEnv *env, jobject obj, jobject peer)
491 ptr = NSA_GET_PTR (env, peer);
493 gdk_threads_enter ();
495 g_signal_connect_after (G_OBJECT (ptr), "realize",
496 G_CALLBACK (realize_cb), obj);
498 gdk_threads_leave ();
501 JNIEXPORT void JNICALL
502 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
503 (JNIEnv *env, jobject obj)
505 struct graphics2d *gr = NULL;
508 gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
512 return; /* dispose has been called more than once */
516 cairo_surface_destroy (gr->surface);
518 cairo_destroy (gr->cr);
521 g_object_unref (gr->drawbuf);
523 g_object_unref (gr->drawable);
526 cairo_pattern_destroy (gr->pattern);
528 if (gr->pattern_surface)
529 cairo_surface_destroy (gr->pattern_surface);
531 if (gr->pattern_pixels)
532 free (gr->pattern_pixels);
534 if (gr->debug) printf ("disposed of graphics2d\n");
541 JNIEXPORT void JNICALL
542 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient
543 (JNIEnv *env, jobject obj,
544 jdouble x1, jdouble y1,
545 jdouble x2, jdouble y2,
546 jint r1, jint g1, jint b1, jint a1,
547 jint r2, jint g2, jint b2, jint a2,
550 struct graphics2d *gr = NULL;
551 cairo_surface_t *surf = NULL;
552 cairo_matrix_t *mat = NULL;
553 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
554 g_assert (gr != NULL);
557 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
558 if (gr->debug) printf ("setGradient (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
567 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2);
569 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2);
570 g_assert (surf != NULL);
572 cairo_set_target_surface (gr->cr, surf);
574 cairo_identity_matrix (gr->cr);
576 cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0);
577 cairo_set_alpha (gr->cr, a1 / 255.0);
578 cairo_rectangle (gr->cr, 0, 0, 1, 2);
581 cairo_set_rgb_color (gr->cr, r2 / 255.0, g2 / 255.0, b2 / 255.0);
582 cairo_set_alpha (gr->cr, a2 / 255.0);
583 cairo_rectangle (gr->cr, 1, 0, 1, 2);
588 cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0);
589 cairo_set_alpha (gr->cr, a1 / 255.0);
590 cairo_rectangle (gr->cr, 2, 0, 1, 2);
594 mat = cairo_matrix_create ();
595 g_assert (mat != NULL);
598 consider the vector [x2 - x1, y2 - y1] = [p,q]
600 this is a line in space starting at an 'origin' x1, y1.
602 it can also be thought of as a "transformed" unit vector in either the
603 x or y directions. we have just *drawn* our gradient as a unit vector
604 (well, a 2-3x unit vector) in the x dimension. so what we want to know
605 is which transformation turns our existing unit vector into [p,q].
607 which means solving for M in
614 [p,q] = [a,c], with b = d = 0.
616 what does this mean? it means that our gradient is 1-dimensional; as
617 you move through the x axis of our 2 or 3 pixel gradient from logical
618 x positions 0 to 1, the transformation of your x coordinate under the
619 matrix M causes you to accumulate both x and y values in fill
620 space. the y value of a gradient coordinate is ignored, since the
621 gradient is one dimensional. which is correct.
623 unfortunately we want the opposite transformation, it seems, because of
624 the way cairo is going to use this transformation. I'm a bit confused by
625 that, but it seems to work right, so we take reciprocals of values and
626 negate offsets. oh well.
630 double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
631 double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
632 double dx = (x1 == 0.) ? 0. : 1. / x1;
633 double dy = (y1 == 0.) ? 0. : 1. / y1;
635 cairo_matrix_set_affine (mat,
640 cairo_surface_set_matrix (surf, mat);
641 cairo_matrix_destroy (mat);
642 cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
645 /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
646 /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
649 cairo_pattern_destroy (gr->pattern);
651 if (gr->pattern_surface)
652 cairo_surface_destroy (gr->pattern_surface);
654 if (gr->pattern_pixels)
655 free (gr->pattern_pixels);
657 gr->pattern_pixels = NULL;
658 gr->pattern_surface = surf;
659 gr->pattern = cairo_pattern_create_for_surface(surf);
661 cairo_restore (gr->cr);
662 cairo_set_pattern (gr->cr, gr->pattern);
666 JNIEXPORT void JNICALL
667 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
668 (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
670 struct graphics2d *gr = NULL;
671 jint *jpixels = NULL;
674 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
675 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
676 g_assert (gr != NULL);
678 if (gr->debug) printf ("setTexturePixels (%d pixels, %dx%d, stride: %d)\n",
679 (*env)->GetArrayLength (env, jarr), w, h, stride);
682 cairo_pattern_destroy (gr->pattern);
684 if (gr->pattern_surface)
685 cairo_surface_destroy (gr->pattern_surface);
687 if (gr->pattern_pixels)
688 free (gr->pattern_pixels);
691 gr->pattern_surface = NULL;
692 gr->pattern_pixels = NULL;
694 gr->pattern_pixels = (char *) malloc (h * stride * 4);
695 g_assert (gr->pattern_pixels != NULL);
697 jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
698 g_assert (jpixels != NULL);
699 memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
700 (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
702 gr->pattern_surface = cairo_surface_create_for_image (gr->pattern_pixels,
705 g_assert (gr->pattern_surface != NULL);
706 cairo_surface_set_repeat (gr->pattern_surface, 1);
707 gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
708 g_assert (gr->pattern != NULL);
709 cairo_set_pattern (gr->cr, gr->pattern);
713 JNIEXPORT void JNICALL
714 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
715 (JNIEnv *env, jobject obj, jintArray java_pixels,
716 jint w, jint h, jint stride, jdoubleArray java_matrix)
718 struct graphics2d *gr = NULL;
719 jint *native_pixels = NULL;
720 jdouble *native_matrix = NULL;
723 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
725 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
726 g_assert (gr != NULL);
728 if (gr->debug) printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
729 (*env)->GetArrayLength (env, java_pixels), w, h, stride);
731 native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
732 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
733 g_assert (native_pixels != NULL);
734 g_assert (native_matrix != NULL);
735 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
737 begin_drawing_operation (gr);
740 cairo_matrix_t *mat = NULL;
741 cairo_surface_t *surf = cairo_surface_create_for_image ((char *)native_pixels,
744 mat = cairo_matrix_create ();
745 cairo_matrix_set_affine (mat,
746 native_matrix[0], native_matrix[1],
747 native_matrix[2], native_matrix[3],
748 native_matrix[4], native_matrix[5]);
749 cairo_surface_set_matrix (surf, mat);
750 cairo_surface_set_filter (surf, cairo_surface_get_filter(gr->surface));
752 cairo_show_surface (gr->cr, surf, w, h);
753 cairo_matrix_destroy (mat);
754 cairo_surface_destroy (surf);
757 end_drawing_operation (gr);
759 (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
760 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
765 JNIEXPORT jintArray JNICALL
766 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getImagePixels
767 (JNIEnv *env, jobject obj)
769 struct graphics2d *gr = NULL;
770 jintArray java_pixels;
772 GdkPixbuf *buf = NULL;
774 gint bits_per_sample = 8;
775 gboolean has_alpha = TRUE;
776 gint total_channels = 4;
780 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return NULL; }
782 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
783 g_assert (gr != NULL);
785 if (gr->debug) printf ("getImagePixels\n");
787 gdk_drawable_get_size (gr->drawable, &width, &height);
789 buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha,
792 g_assert (buf != NULL);
793 g_assert (gdk_pixbuf_get_bits_per_sample (buf) == bits_per_sample);
794 g_assert (gdk_pixbuf_get_n_channels (buf) == total_channels);
797 /* copy pixels from drawable to pixbuf */
799 gdk_pixbuf_get_from_drawable (buf, gr->drawable,
804 native_pixels= gdk_pixbuf_get_pixels (buf);
806 #ifndef WORDS_BIGENDIAN
807 /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
808 for (i=0; i<width * height; i++)
810 native_pixels[i] = SWAPU32 ((unsigned)native_pixels[i]);
814 java_pixels = (*env) -> NewIntArray (env, width * height);
816 (*env)->SetIntArrayRegion(env, java_pixels,
817 (jsize)0, (jsize) width*height,
818 (jint*) native_pixels);
824 /* passthrough methods to cairo */
826 JNIEXPORT void JNICALL
827 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave
828 (JNIEnv *env, jobject obj)
830 struct graphics2d *gr = NULL;
833 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
835 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
836 g_assert (gr != NULL);
837 if (gr->debug) printf ("cairo_save\n");
842 JNIEXPORT void JNICALL
843 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
844 (JNIEnv *env, jobject obj)
846 struct graphics2d *gr = NULL;
849 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
851 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
852 g_assert (gr != NULL);
853 if (gr->debug) printf ("cairo_restore\n");
854 cairo_restore (gr->cr);
855 update_pattern_transform (gr);
859 JNIEXPORT void JNICALL
860 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
861 (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
863 struct graphics2d *gr = NULL;
864 jdouble *native_matrix = NULL;
867 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
869 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
870 /* cairoSetMatrix was called before this graphics object's component
872 if (gr == NULL) { gdk_threads_leave (); return; }
874 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
875 g_assert (native_matrix != NULL);
876 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
878 if (gr->debug) printf ("cairo_set_matrix [ %f, %f, %f, %f, %f, %f ]\n",
879 native_matrix[0], native_matrix[1],
880 native_matrix[2], native_matrix[3],
881 native_matrix[4], native_matrix[5]);
884 cairo_matrix_t * mat = cairo_matrix_create ();
885 cairo_matrix_set_affine (mat,
886 native_matrix[0], native_matrix[1],
887 native_matrix[2], native_matrix[3],
888 native_matrix[4], native_matrix[5]);
889 cairo_set_matrix (gr->cr, mat);
890 cairo_matrix_destroy (mat);
893 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
894 update_pattern_transform (gr);
899 install_font_peer(cairo_t *cr,
900 struct peerfont *pfont,
906 g_assert(cr != NULL);
907 g_assert(pfont != NULL);
909 if (pfont->graphics_resource == NULL)
911 face = pango_ft2_font_get_face (pfont->font);
912 g_assert (face != NULL);
914 ft = cairo_ft_font_create_for_ft_face (face);
915 g_assert (ft != NULL);
917 if (debug) printf ("install_font_peer made new cairo font for '%s' at %f\n",
919 (pango_font_description_get_size (pfont->desc) /
920 (double)PANGO_SCALE) * (96.0 / 72.0));
922 cairo_set_font (cr, ft);
923 cairo_font_destroy (ft);
924 cairo_scale_font (cr,
925 (pango_font_description_get_size (pfont->desc) /
926 (double)PANGO_SCALE) * (96.0 / 72.0));
927 ft = cairo_current_font (cr);
928 pfont->graphics_resource = ft;
932 if (debug) printf ("install_font_peer reused existing font resource\n");
933 ft = (cairo_font_t *) pfont->graphics_resource;
934 cairo_set_font (cr, ft);
938 static cairo_t *metrics_cairo = NULL;
939 static cairo_surface_t *metrics_surface = NULL;
942 ensure_metrics_cairo()
944 if (metrics_cairo == NULL)
946 metrics_cairo = cairo_create ();
947 metrics_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, 1, 1);
948 cairo_set_target_surface (metrics_cairo, metrics_surface);
953 JNIEXPORT void JNICALL
954 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
955 (JNIEnv *env, jclass clazz, jobject java_font)
957 struct peerfont *pfont = NULL;
959 g_assert(java_font != NULL);
962 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
963 g_assert (pfont != NULL);
964 if (pfont->graphics_resource != NULL)
966 cairo_font_destroy ((cairo_font_t *) pfont->graphics_resource);
967 pfont->graphics_resource = NULL;
972 JNIEXPORT void JNICALL
973 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerTextMetrics
974 (JNIEnv *env, jclass clazz, jobject java_font, jstring str, jdoubleArray java_metrics)
976 struct peerfont *pfont = NULL;
977 const char *cstr = NULL;
978 jdouble *native_metrics = NULL;
979 cairo_text_extents_t extents;
981 g_assert(java_font != NULL);
984 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font);
985 g_assert (pfont != NULL);
987 ensure_metrics_cairo();
988 install_font_peer (metrics_cairo, pfont, 0);
990 cstr = (*env)->GetStringUTFChars (env, str, NULL);
991 g_assert(cstr != NULL);
992 cairo_text_extents (metrics_cairo, cstr, &extents);
994 native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
995 g_assert (native_metrics != NULL);
997 native_metrics[TEXT_METRICS_X_BEARING] = extents.x_bearing;
998 native_metrics[TEXT_METRICS_Y_BEARING] = extents.y_bearing;
999 native_metrics[TEXT_METRICS_WIDTH] = extents.width;
1000 native_metrics[TEXT_METRICS_HEIGHT] = extents.height;
1001 native_metrics[TEXT_METRICS_X_ADVANCE] = extents.x_advance;
1002 native_metrics[TEXT_METRICS_Y_ADVANCE] = extents.y_advance;
1004 (*env)->ReleaseStringUTFChars (env, str, cstr);
1005 (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
1006 gdk_threads_leave();
1009 JNIEXPORT void JNICALL
1010 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getPeerFontMetrics
1011 (JNIEnv *env, jclass clazz, jobject java_font, jdoubleArray java_metrics)
1013 struct peerfont *pfont = NULL;
1014 jdouble *native_metrics = NULL;
1015 cairo_font_extents_t extents;
1017 g_assert(java_font != NULL);
1019 gdk_threads_enter();
1021 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font);
1022 g_assert (pfont != NULL);
1024 ensure_metrics_cairo();
1025 install_font_peer (metrics_cairo, pfont, 0);
1027 cairo_current_font_extents (metrics_cairo, &extents);
1029 native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
1030 g_assert (native_metrics != NULL);
1032 native_metrics[FONT_METRICS_ASCENT] = extents.ascent;
1033 native_metrics[FONT_METRICS_MAX_ASCENT] = extents.ascent;
1034 native_metrics[FONT_METRICS_DESCENT] = extents.descent;
1035 if (native_metrics[FONT_METRICS_DESCENT] < 0)
1036 native_metrics[FONT_METRICS_DESCENT] = - native_metrics[FONT_METRICS_DESCENT];
1037 native_metrics[FONT_METRICS_MAX_DESCENT] = native_metrics[FONT_METRICS_DESCENT];
1038 native_metrics[FONT_METRICS_MAX_ADVANCE] = extents.max_x_advance;
1040 (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
1041 gdk_threads_leave();
1045 paint_glyph_run(struct graphics2d *gr,
1046 cairo_glyph_t **glyphs,
1048 PangoLayoutRun *run)
1053 g_assert (gr != NULL);
1054 g_assert (glyphs != NULL);
1055 g_assert (n_glyphs != NULL);
1056 g_assert (run != NULL);
1058 if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
1060 if (*n_glyphs < run->glyphs->num_glyphs)
1062 *glyphs = g_realloc(*glyphs,
1063 (sizeof(cairo_glyph_t)
1064 * run->glyphs->num_glyphs));
1065 *n_glyphs = run->glyphs->num_glyphs;
1068 g_assert (*glyphs != NULL);
1070 if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs);
1072 for (i = 0; i < run->glyphs->num_glyphs; ++i)
1074 (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
1077 ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
1078 / ((double) PANGO_SCALE);
1081 ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
1082 / ((double) PANGO_SCALE);
1084 if (gr->debug) printf(" (%ld @ %f,%f)",
1089 x += run->glyphs->glyphs[i].geometry.width;
1092 if (gr->debug) printf("\n");
1093 begin_drawing_operation (gr);
1094 cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs);
1095 end_drawing_operation (gr);
1099 JNIEXPORT void JNICALL
1100 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawString
1101 (JNIEnv *env, jobject obj, jobject font, jstring str, float x, float y)
1103 struct graphics2d *gr = NULL;
1104 const char *cstr = NULL;
1105 struct peerfont *pfont = NULL;
1108 cairo_glyph_t *glyphs = NULL;
1110 PangoLayoutRun *run = NULL;
1111 PangoLayoutIter *iter = NULL;
1114 g_assert(obj != NULL);
1115 g_assert(font != NULL);
1116 g_assert(str != NULL);
1118 gdk_threads_enter ();
1119 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1121 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1122 g_assert(gr != NULL);
1124 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, font);
1125 g_assert (pfont != NULL);
1127 cstr = (*env)->GetStringUTFChars (env, str, NULL);
1128 g_assert(cstr != NULL);
1130 if (gr->debug) printf ("painting string '%s' at (%f,%f)\n", cstr, x, y);
1132 /* For now we let cairo do the glyph conversion; eventually this
1133 * ought to be unified with pango, but it is impossible to get
1134 * pango and cairo to agree on metrics at the moment, so we either
1135 * have to use "all cairo" metrics (the string-based APIs) or
1136 * "all pango" metrics (the glyph-vector based APIs).
1139 install_font_peer (gr->cr, pfont, gr->debug);
1140 cairo_move_to (gr->cr, x, y);
1141 cairo_show_text (gr->cr, cstr);
1145 pango_layout_set_text (gr->pango_layout, cstr, -1);
1147 iter = pango_layout_get_iter (gr->pango_layout);
1148 g_assert(iter != NULL);
1150 cairo_translate (gr->cr, x, y);
1154 run = pango_layout_iter_get_run (iter);
1156 paint_glyph_run (gr, &glyphs, &n_glyphs, run);
1158 while (pango_layout_iter_next_run (iter));
1163 cairo_translate (gr->cr, -x, -y);
1165 pango_layout_iter_free (iter);
1169 gdk_threads_leave ();
1171 (*env)->ReleaseStringUTFChars (env, str, cstr);
1175 JNIEXPORT void JNICALL
1176 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkGlyphVector
1177 (JNIEnv *env, jobject self, jobject font, jobject java_vec, jfloat x, jfloat y)
1180 struct graphics2d *gr = NULL;
1181 struct peerfont *pfont = NULL;
1182 struct glyphvec *gv = NULL;
1183 PangoLayoutRun *run = NULL;
1184 cairo_glyph_t *glyphs = NULL;
1187 g_assert (self != NULL);
1188 g_assert (java_vec != NULL);
1190 gdk_threads_enter ();
1191 if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; }
1193 gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
1194 gv = (struct glyphvec *)NSA_GET_GV_PTR (env, java_vec);
1195 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, font);
1197 g_assert (gr != NULL);
1198 g_assert (gv != NULL);
1199 g_assert (pfont != NULL);
1201 if (gr->debug) printf ("painting pango glyph vector\n");
1203 install_font_peer (gr->cr, pfont, gr->debug);
1204 cairo_translate (gr->cr, x, y);
1206 /* nb. PangoLayoutRun is a typedef for PangoGlyphItem. */
1207 run = (PangoLayoutRun *) gv->glyphitems;
1209 paint_glyph_run (gr, &glyphs, &n_glyphs, run);
1214 cairo_translate (gr->cr, -x, -y);
1215 gdk_threads_leave ();
1218 JNIEXPORT void JNICALL
1219 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout
1220 (JNIEnv *env, jobject self, jobject font, jobject java_layout, jfloat x, jfloat y)
1223 * FIXME: Some day we expect either cairo or pango will know how to make
1224 * a pango layout paint to a cairo surface. that day is not yet here.
1227 struct graphics2d *gr = NULL;
1228 struct peerfont *pfont = NULL;
1229 struct textlayout *tl = NULL;
1230 PangoLayoutIter *i = NULL;
1231 PangoLayoutRun *run = NULL;
1232 cairo_glyph_t *glyphs = NULL;
1235 g_assert (self != NULL);
1236 g_assert (java_layout != NULL);
1238 gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
1239 tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout);
1240 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, font);
1242 g_assert (gr != NULL);
1243 g_assert (tl != NULL);
1244 g_assert (tl->pango_layout != NULL);
1245 g_assert (pfont != NULL);
1247 if (gr->debug) printf ("painting pango layout\n");
1249 gdk_threads_enter ();
1250 if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; }
1252 i = pango_layout_get_iter (tl->pango_layout);
1253 g_assert (i != NULL);
1255 install_font_peer (gr->cr, pfont, gr->debug);
1256 cairo_translate (gr->cr, x, y);
1260 run = pango_layout_iter_get_run (i);
1262 paint_glyph_run (gr, &glyphs, &n_glyphs, run);
1264 while (pango_layout_iter_next_run (i));
1269 cairo_translate (gr->cr, -x, -y);
1271 pango_layout_iter_free (i);
1272 gdk_threads_leave ();
1275 JNIEXPORT void JNICALL
1276 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
1277 (JNIEnv *env, jobject obj, jint op)
1279 struct graphics2d *gr = NULL;
1281 gdk_threads_enter();
1282 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1284 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1285 g_assert (gr != NULL);
1286 if (gr->debug) printf ("cairo_set_operator %d\n", op);
1287 switch ((enum java_awt_alpha_composite_rule) op)
1289 case java_awt_alpha_composite_CLEAR:
1290 cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
1293 case java_awt_alpha_composite_SRC:
1294 cairo_set_operator (gr->cr, CAIRO_OPERATOR_SRC);
1297 case java_awt_alpha_composite_SRC_OVER:
1298 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
1301 case java_awt_alpha_composite_DST_OVER:
1302 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER_REVERSE);
1305 case java_awt_alpha_composite_SRC_IN:
1306 cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
1309 case java_awt_alpha_composite_DST_IN:
1310 cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN_REVERSE);
1313 case java_awt_alpha_composite_SRC_OUT:
1314 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
1317 case java_awt_alpha_composite_DST_OUT:
1318 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT_REVERSE);
1321 case java_awt_alpha_composite_DST:
1322 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DST);
1325 case java_awt_alpha_composite_SRC_ATOP:
1326 cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
1329 case java_awt_alpha_composite_DST_ATOP:
1330 cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP_REVERSE);
1333 case java_awt_alpha_composite_XOR:
1334 cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
1337 gdk_threads_leave();
1340 JNIEXPORT void JNICALL
1341 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBColor
1342 (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b)
1344 struct graphics2d *gr = NULL;
1346 gdk_threads_enter();
1347 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1349 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1350 g_assert (gr != NULL);
1352 /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider
1353 colors in opposite pixel order. I have no idea why. thus when you
1354 draw to a PixBuf, you must exchange the R and B components of your
1357 if (gr->debug) printf ("cairo_set_rgb_color (%f, %f, %f)\n", r, g, b);
1360 cairo_set_rgb_color (gr->cr, b, g, r);
1362 cairo_set_rgb_color (gr->cr, r, g, b);
1364 gdk_threads_leave();
1367 JNIEXPORT void JNICALL
1368 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetAlpha
1369 (JNIEnv *env, jobject obj, jdouble a)
1371 struct graphics2d *gr = NULL;
1373 gdk_threads_enter();
1374 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1376 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1377 g_assert (gr != NULL);
1378 if (gr->debug) printf ("cairo_set_alpha %f\n", a);
1379 cairo_set_alpha (gr->cr, a);
1380 gdk_threads_leave();
1383 JNIEXPORT void JNICALL
1384 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule
1385 (JNIEnv *env, jobject obj, jint rule)
1387 struct graphics2d *gr = NULL;
1389 gdk_threads_enter();
1390 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1392 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1393 if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
1394 g_assert (gr != NULL);
1395 switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
1397 case java_awt_geom_path_iterator_WIND_NON_ZERO:
1398 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
1400 case java_awt_geom_path_iterator_WIND_EVEN_ODD:
1401 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
1404 gdk_threads_leave();
1407 JNIEXPORT void JNICALL
1408 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth
1409 (JNIEnv *env, jobject obj, jdouble width)
1411 struct graphics2d *gr = NULL;
1413 gdk_threads_enter();
1414 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1416 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1417 g_assert (gr != NULL);
1418 if (gr->debug) printf ("cairo_set_line_width %f\n", width);
1419 cairo_set_line_width (gr->cr, width);
1420 gdk_threads_leave();
1423 JNIEXPORT void JNICALL
1424 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap
1425 (JNIEnv *env, jobject obj, jint cap)
1427 struct graphics2d *gr = NULL;
1429 gdk_threads_enter();
1430 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1432 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1433 g_assert (gr != NULL);
1434 if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
1435 switch ((enum java_awt_basic_stroke_cap_rule) cap)
1437 case java_awt_basic_stroke_CAP_BUTT:
1438 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
1441 case java_awt_basic_stroke_CAP_ROUND:
1442 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
1445 case java_awt_basic_stroke_CAP_SQUARE:
1446 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
1449 gdk_threads_leave();
1452 JNIEXPORT void JNICALL
1453 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin
1454 (JNIEnv *env, jobject obj, jint join)
1456 struct graphics2d *gr = NULL;
1458 gdk_threads_enter();
1459 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1461 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1462 g_assert (gr != NULL);
1463 if (gr->debug) printf ("cairo_set_line_join %d\n", join);
1464 switch ((enum java_awt_basic_stroke_join_rule) join)
1466 case java_awt_basic_stroke_JOIN_MITER:
1467 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
1470 case java_awt_basic_stroke_JOIN_ROUND:
1471 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
1474 case java_awt_basic_stroke_JOIN_BEVEL:
1475 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
1478 gdk_threads_leave();
1481 JNIEXPORT void JNICALL
1482 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash
1483 (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
1485 struct graphics2d *gr = NULL;
1486 jdouble *dasharr = NULL;
1488 gdk_threads_enter();
1489 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1491 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1492 g_assert (gr != NULL);
1493 if (gr->debug) printf ("cairo_set_dash\n");
1494 dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
1495 g_assert (dasharr != NULL);
1496 cairo_set_dash (gr->cr, dasharr, ndash, offset);
1497 (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
1498 gdk_threads_leave();
1501 JNIEXPORT void JNICALL
1502 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit
1503 (JNIEnv *env, jobject obj, jdouble miter)
1505 struct graphics2d *gr = NULL;
1507 gdk_threads_enter();
1508 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1510 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1511 g_assert (gr != NULL);
1512 if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
1513 cairo_set_miter_limit (gr->cr, miter);
1514 gdk_threads_leave();
1518 JNIEXPORT void JNICALL
1519 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath
1520 (JNIEnv *env, jobject obj)
1522 struct graphics2d *gr = NULL;
1524 gdk_threads_enter();
1525 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1527 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1528 if (gr == NULL) { gdk_threads_leave (); return; }
1529 if (gr->debug) printf ("cairo_new_path\n");
1530 cairo_new_path (gr->cr);
1531 gdk_threads_leave();
1534 JNIEXPORT void JNICALL
1535 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo
1536 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
1538 struct graphics2d *gr = NULL;
1540 gdk_threads_enter();
1541 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1543 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1544 g_assert (gr != NULL);
1545 if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y);
1546 cairo_move_to (gr->cr, x, y);
1547 gdk_threads_leave();
1550 JNIEXPORT void JNICALL
1551 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo
1552 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
1554 struct graphics2d *gr = NULL;
1556 gdk_threads_enter();
1557 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1559 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1560 g_assert (gr != NULL);
1561 if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y);
1562 cairo_line_to (gr->cr, x, y);
1563 gdk_threads_leave();
1566 JNIEXPORT void JNICALL
1567 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo
1568 (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
1570 struct graphics2d *gr = NULL;
1572 gdk_threads_enter();
1573 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1575 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1576 g_assert (gr != NULL);
1577 if (gr->debug) printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n", x1, y1, x2, y2, x3, y3);
1578 cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
1579 gdk_threads_leave();
1582 JNIEXPORT void JNICALL
1583 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo
1584 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1586 struct graphics2d *gr = NULL;
1588 gdk_threads_enter();
1589 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1591 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1592 g_assert (gr != NULL);
1593 if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
1594 cairo_rel_move_to (gr->cr, dx, dy);
1595 gdk_threads_leave();
1598 JNIEXPORT void JNICALL
1599 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo
1600 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1602 struct graphics2d *gr = NULL;
1604 gdk_threads_enter();
1605 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1607 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1608 g_assert (gr != NULL);
1609 if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
1610 cairo_rel_line_to (gr->cr, dx, dy);
1611 gdk_threads_leave();
1614 JNIEXPORT void JNICALL
1615 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo
1616 (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
1618 struct graphics2d *gr = NULL;
1620 gdk_threads_enter();
1621 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1623 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1624 g_assert (gr != NULL);
1625 if (gr->debug) printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n", dx1, dy1, dx2, dy2, dx3, dy3);
1626 cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
1627 gdk_threads_leave();
1630 JNIEXPORT void JNICALL
1631 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle
1632 (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
1634 struct graphics2d *gr = NULL;
1636 gdk_threads_enter();
1637 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1639 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1640 if (gr == NULL) { gdk_threads_leave (); return; }
1641 if (gr->debug) printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
1642 cairo_rectangle (gr->cr, x, y, width, height);
1643 gdk_threads_leave();
1646 JNIEXPORT void JNICALL
1647 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath
1648 (JNIEnv *env, jobject obj)
1650 struct graphics2d *gr = NULL;
1652 gdk_threads_enter();
1653 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1655 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1656 g_assert (gr != NULL);
1657 if (gr->debug) printf ("cairo_close_path\n");
1658 cairo_close_path (gr->cr);
1659 gdk_threads_leave();
1662 JNIEXPORT void JNICALL
1663 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
1664 (JNIEnv *env, jobject obj)
1666 struct graphics2d *gr = NULL;
1668 gdk_threads_enter();
1669 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1671 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1672 g_assert (gr != NULL);
1673 if (gr->debug) printf ("cairo_stroke\n");
1674 begin_drawing_operation (gr);
1675 cairo_stroke (gr->cr);
1676 end_drawing_operation (gr);
1677 gdk_threads_leave();
1680 JNIEXPORT void JNICALL
1681 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
1682 (JNIEnv *env, jobject obj)
1684 struct graphics2d *gr = NULL;
1686 gdk_threads_enter();
1687 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1689 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1690 g_assert (gr != NULL);
1691 if (gr->debug) printf ("cairo_fill\n");
1692 begin_drawing_operation (gr);
1693 cairo_fill (gr->cr);
1694 end_drawing_operation (gr);
1695 gdk_threads_leave();
1698 JNIEXPORT void JNICALL
1699 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
1700 (JNIEnv *env, jobject obj)
1702 struct graphics2d *gr = NULL;
1704 gdk_threads_enter();
1705 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1707 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1708 if (gr == NULL) { gdk_threads_leave (); return; }
1709 if (gr->debug) printf ("cairo_clip\n");
1710 begin_drawing_operation (gr);
1711 cairo_init_clip (gr->cr);
1712 cairo_clip (gr->cr);
1713 end_drawing_operation (gr);
1714 gdk_threads_leave();
1717 JNIEXPORT void JNICALL
1718 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
1719 (JNIEnv *env, jobject obj, jint filter)
1721 struct graphics2d *gr = NULL;
1723 gdk_threads_enter();
1724 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1726 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1727 g_assert (gr != NULL);
1728 if (gr->debug) printf ("cairo_surface_set_filter %d\n", filter);
1729 switch ((enum java_awt_rendering_hints_filter) filter)
1731 case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
1732 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
1734 case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
1735 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BILINEAR);
1737 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
1738 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
1740 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
1741 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
1743 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
1744 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BEST);
1747 gdk_threads_leave();