Merge from the pain train
[official-gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GdkGraphics2D.c
blobe6535b46324aaad5ceb3cd48ac3f3633040ee78e
1 /* gnu_java_awt_peer_gtk_GdkGraphics2d.c
2 Copyright (C) 2003, 2005 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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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 "gtkcairopeer.h"
39 #include "gdkfont.h"
40 #include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
41 #include <gdk/gdktypes.h>
42 #include <gdk/gdkprivate.h>
43 #include <gdk/gdkx.h>
45 #include <gdk-pixbuf/gdk-pixbuf.h>
46 #include <gdk-pixbuf/gdk-pixdata.h>
48 #include <cairo-ft.h>
49 #include <cairo-xlib.h>
51 #include <stdio.h>
52 #include <stdlib.h>
54 struct state_table *native_graphics2d_state_table;
56 #define NSA_G2D_INIT(env, clazz) \
57 native_graphics2d_state_table = init_state_table (env, clazz)
59 #define NSA_GET_G2D_PTR(env, obj) \
60 get_state (env, obj, native_graphics2d_state_table)
62 #define NSA_SET_G2D_PTR(env, obj, ptr) \
63 set_state (env, obj, native_graphics2d_state_table, (void *)ptr)
65 #define NSA_DEL_G2D_PTR(env, obj) \
66 remove_state_slot (env, obj, native_graphics2d_state_table)
68 JNIEXPORT void JNICALL
69 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState
70 (JNIEnv *env, jclass clazz)
72 gdk_threads_enter();
73 NSA_G2D_INIT (env, clazz);
74 gdk_threads_leave();
77 /* these public final constants are part of the java2d public API, so we
78 write them explicitly here to save fetching them from the constant pool
79 all the time. */
81 #ifndef min
82 #define min(x,y) ((x) < (y) ? (x) : (y))
83 #endif
85 enum java_awt_alpha_composite_rule
87 java_awt_alpha_composite_CLEAR = 1,
88 java_awt_alpha_composite_SRC = 2,
89 java_awt_alpha_composite_SRC_OVER = 3,
90 java_awt_alpha_composite_DST_OVER = 4,
91 java_awt_alpha_composite_SRC_IN = 5,
92 java_awt_alpha_composite_DST_IN = 6,
93 java_awt_alpha_composite_SRC_OUT = 7,
94 java_awt_alpha_composite_DST_OUT = 8,
95 java_awt_alpha_composite_DST = 9,
96 java_awt_alpha_composite_SRC_ATOP = 10,
97 java_awt_alpha_composite_DST_ATOP = 11,
98 java_awt_alpha_composite_XOR = 12
101 enum java_awt_basic_stroke_join_rule
103 java_awt_basic_stroke_JOIN_MITER = 0,
104 java_awt_basic_stroke_JOIN_ROUND = 1,
105 java_awt_basic_stroke_JOIN_BEVEL = 2
108 enum java_awt_basic_stroke_cap_rule
110 java_awt_basic_stroke_CAP_BUTT = 0,
111 java_awt_basic_stroke_CAP_ROUND = 1,
112 java_awt_basic_stroke_CAP_SQUARE = 2
115 enum java_awt_geom_path_iterator_winding_rule
117 java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
118 java_awt_geom_path_iterator_WIND_NON_ZERO = 1
121 enum java_awt_rendering_hints_filter
123 java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
124 java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
125 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
126 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
127 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
131 static int
132 peer_is_disposed(JNIEnv *env, jobject obj)
134 static jfieldID fid = NULL;
135 jclass cls;
136 jobject peer;
138 return 0;
140 if (fid == NULL)
142 cls = (*env)->GetObjectClass(env, obj);
143 fid = (*env)->GetFieldID(env, cls, "component",
144 "Lgnu/java/awt/peer/gtk/GtkComponentPeer;");
146 g_assert(fid != NULL);
147 peer = (*env)->GetObjectField(env, obj, fid);
148 if (peer == NULL || NSA_GET_PTR (env, peer) != NULL)
149 return 0;
150 else
152 return 1;
157 static void
158 grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
160 g_assert (widget != NULL);
161 g_assert (draw != NULL);
162 g_assert (win != NULL);
164 *win = widget->window;
166 *draw = *win;
167 gdk_window_get_internal_paint_info (*win, draw, 0, 0);
168 g_object_ref (*draw);
172 static int
173 x_server_has_render_extension (void)
175 int ev = 0, err = 0;
176 return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
179 static void
180 init_graphics2d_as_pixbuf (struct graphics2d *gr)
182 gint width, height;
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,
194 width, height);
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 ((char *) gdk_pixbuf_get_pixels (gr->drawbuf),
200 CAIRO_FORMAT_ARGB32,
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 gr->mode = MODE_DRAWABLE_NO_RENDER;
207 cairo_set_target_surface (gr->cr, gr->surface);
210 static void
211 init_graphics2d_as_renderable (struct graphics2d *gr)
213 Drawable draw;
214 Display * dpy;
215 Visual * vis;
217 g_assert (gr != NULL);
218 g_assert (gr->drawable != NULL);
220 gr->drawbuf = NULL;
222 if (gr->debug) printf ("initializing graphics2d as renderable\n");
223 draw = gdk_x11_drawable_get_xid (gr->drawable);
225 dpy = gdk_x11_drawable_get_xdisplay (gr->drawable);
226 g_assert (dpy != NULL);
228 vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
229 g_assert (vis != NULL);
231 gr->surface = cairo_xlib_surface_create (dpy, draw, vis,
232 CAIRO_FORMAT_ARGB32,
233 DefaultColormap (dpy, DefaultScreen (dpy)));
234 g_assert (gr->surface != NULL);
235 g_assert (gr->cr != NULL);
236 gr->mode = MODE_DRAWABLE_WITH_RENDER;
237 cairo_set_target_surface (gr->cr, gr->surface);
240 static void
241 begin_drawing_operation (JNIEnv *env, struct graphics2d * gr)
243 g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
245 switch (gr->mode)
247 case MODE_DRAWABLE_WITH_RENDER:
248 break;
250 case MODE_DRAWABLE_NO_RENDER:
253 gint drawable_width, drawable_height;
254 gint pixbuf_width, pixbuf_height;
255 gint width, height;
257 gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
258 pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
259 pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
260 width = min (drawable_width, pixbuf_width);
261 height = min (drawable_height, pixbuf_height);
263 gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
264 gr->drawable,
265 NULL, /* colormap */
266 0, 0, 0, 0,
267 width, height);
269 if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
270 width, height);
272 break;
274 case MODE_JAVA_ARRAY:
275 gr->javabuf = (*env)->GetIntArrayElements (env, gr->jarray, &gr->isCopy);
276 gr->surface = cairo_surface_create_for_image ((char *) gr->javabuf,
277 CAIRO_FORMAT_ARGB32,
278 gr->width,
279 gr->height,
280 gr->width * 4);
281 g_assert(gr->surface != NULL);
282 g_assert(gr->cr != NULL);
283 cairo_set_target_surface (gr->cr, gr->surface);
284 break;
288 static void
289 end_drawing_operation (JNIEnv *env, struct graphics2d * gr)
291 g_assert(cairo_status (gr->cr) == CAIRO_STATUS_SUCCESS);
293 switch (gr->mode)
295 case MODE_DRAWABLE_WITH_RENDER:
296 break;
298 case MODE_DRAWABLE_NO_RENDER:
301 gint drawable_width, drawable_height;
302 gint pixbuf_width, pixbuf_height;
303 gint width, height;
305 gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
306 pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
307 pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
308 width = min (drawable_width, pixbuf_width);
309 height = min (drawable_height, pixbuf_height);
311 gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
312 0, 0, 0, 0,
313 width, height,
314 GDK_RGB_DITHER_NORMAL, 0, 0);
316 if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
317 width, height);
319 break;
321 case MODE_JAVA_ARRAY:
323 * FIXME: Perhaps this should use the isCopy flag to try to avoid
324 * tearing down the cairo surface.
326 cairo_surface_destroy (gr->surface);
327 gr->surface = NULL;
328 (*env)->ReleaseIntArrayElements (env, gr->jarray, gr->javabuf, JNI_COMMIT);
333 static void
334 update_pattern_transform (struct graphics2d *gr)
336 double a, b, c, d, tx, ty;
337 cairo_matrix_t *mat = NULL;
339 g_assert (gr != NULL);
340 if (gr->pattern == NULL)
341 return;
343 return;
344 /* temporarily disabled: ambiguous behavior */
345 /* cairo_get_matrix (gr->cr, &a, &b, &c, &d, &tx, &ty); */
346 mat = cairo_matrix_create ();
347 g_assert (mat != NULL);
348 cairo_matrix_set_affine (mat, a, b, c, d, tx, ty);
349 cairo_pattern_set_matrix (gr->pattern, mat);
350 cairo_matrix_destroy (mat);
353 static void
354 check_for_debug (struct graphics2d *gr)
356 gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL);
359 static void
360 realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject peer)
362 gdk_threads_leave ();
364 (*gdk_env())->CallVoidMethod (gdk_env(), peer, initComponentGraphics2DID);
366 gdk_threads_enter ();
369 JNIEXPORT void JNICALL
370 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
371 (JNIEnv *env, jobject obj, jobject old)
373 struct graphics2d *g = NULL, *g_old = NULL;
375 gdk_threads_enter();
376 g = (struct graphics2d *) malloc (sizeof (struct graphics2d));
377 g_assert (g != NULL);
378 memset (g, 0, sizeof(struct graphics2d));
380 g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
381 g_assert (g_old != NULL);
383 if (g_old->debug) printf ("copying state from existing graphics2d\n");
385 g->debug = g_old->debug;
386 g->mode = g_old->mode;
388 if (g_old->mode == MODE_JAVA_ARRAY)
390 g->width = g_old->width;
391 g->height = g_old->height;
392 g->jarray = (*env)->NewGlobalRef(env, g_old->jarray);
394 else
396 g->drawable = g_old->drawable;
398 g_object_ref (g->drawable);
400 g->cr = cairo_create();
401 g_assert (g->cr != NULL);
403 if (x_server_has_render_extension ())
404 init_graphics2d_as_renderable (g);
405 else
406 init_graphics2d_as_pixbuf (g);
409 cairo_surface_set_filter (g->surface, CAIRO_FILTER_FAST);
411 NSA_SET_G2D_PTR (env, obj, g);
412 gdk_threads_leave();
416 JNIEXPORT void JNICALL
417 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III
418 (JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height)
420 struct graphics2d *gr;
422 gdk_threads_enter();
423 gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
424 g_assert (gr != NULL);
425 memset (gr, 0, sizeof(struct graphics2d));
427 check_for_debug (gr);
429 if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n",
430 width, height);
432 gr->cr = cairo_create();
433 g_assert (gr->cr != NULL);
435 gr->width = width;
436 gr->height = height;
437 gr->jarray = (*env)->NewGlobalRef(env, jarr);
438 gr->mode = MODE_JAVA_ARRAY;
440 if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n",
441 width, height);
443 NSA_SET_G2D_PTR (env, obj, gr);
444 gdk_threads_leave();
447 JNIEXPORT void JNICALL
448 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
449 (JNIEnv *env, jobject obj, jint width, jint height)
451 struct graphics2d *gr;
453 gdk_threads_enter();
454 gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
455 g_assert (gr != NULL);
456 memset (gr, 0, sizeof(struct graphics2d));
458 check_for_debug (gr);
460 if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
461 width, height);
463 gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
464 gdk_rgb_get_visual ()->depth);
465 g_assert (gr->drawable != NULL);
467 gr->cr = cairo_create();
468 g_assert (gr->cr != NULL);
470 if (x_server_has_render_extension ())
471 init_graphics2d_as_renderable (gr);
472 else
473 init_graphics2d_as_pixbuf (gr);
475 if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
476 width, height);
477 NSA_SET_G2D_PTR (env, obj, gr);
478 gdk_threads_leave();
481 JNIEXPORT void JNICALL
482 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
483 (JNIEnv *env, jobject self, jobject other, jint x, jint y)
485 struct graphics2d *src = NULL, *dst = NULL;
486 gint s_height, s_width, d_height, d_width, height, width;
487 cairo_matrix_t *matrix;
488 cairo_operator_t tmp_op;
490 gdk_threads_enter();
491 if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; }
492 src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
493 dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
494 g_assert (src != NULL);
495 g_assert (dst != NULL);
497 if (src->debug) printf ("copying from offscreen drawable\n");
499 begin_drawing_operation(env, dst);
501 /* gdk_flush(); */
503 gdk_drawable_get_size (src->drawable, &s_width, &s_height);
504 gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
505 width = min (s_width, d_width);
506 height = min (s_height, d_height);
508 matrix = cairo_matrix_create ();
509 cairo_surface_get_matrix (src->surface, matrix);
510 cairo_matrix_translate (matrix, (double)-x, (double)-y);
511 cairo_surface_set_matrix (src->surface, matrix);
513 tmp_op = cairo_current_operator (dst->cr);
514 cairo_set_operator(dst->cr, CAIRO_OPERATOR_SRC);
515 cairo_show_surface (dst->cr, src->surface, width, height);
516 cairo_set_operator(dst->cr, tmp_op);
518 cairo_matrix_translate (matrix, (double)x, (double)y);
519 cairo_surface_set_matrix (src->surface, matrix);
520 cairo_matrix_destroy (matrix);
522 gdk_flush();
524 end_drawing_operation(env, dst);
526 if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
527 gdk_threads_leave();
530 JNIEXPORT void JNICALL
531 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
532 (JNIEnv *env, jobject obj, jobject peer)
534 struct graphics2d *gr = NULL;
535 GtkWidget *widget = NULL;
536 void *ptr = NULL;
538 gdk_threads_enter();
539 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
540 ptr = NSA_GET_PTR (env, peer);
541 g_assert (ptr != NULL);
543 gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
544 g_assert (gr != NULL);
545 memset (gr, 0, sizeof(struct graphics2d));
547 check_for_debug (gr);
549 gr->cr = cairo_create();
550 g_assert (gr->cr != NULL);
552 widget = GTK_WIDGET (ptr);
553 g_assert (widget != NULL);
555 grab_current_drawable (widget, &(gr->drawable), &(gr->win));
556 g_assert (gr->drawable != NULL);
558 if (x_server_has_render_extension ())
559 init_graphics2d_as_renderable (gr);
560 else
561 init_graphics2d_as_pixbuf (gr);
563 NSA_SET_G2D_PTR (env, obj, gr);
564 gdk_threads_leave();
567 JNIEXPORT void JNICALL
568 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_connectSignals
569 (JNIEnv *env, jobject obj, jobject peer)
571 void *ptr;
573 ptr = NSA_GET_PTR (env, peer);
575 gdk_threads_enter ();
577 g_signal_connect_after (G_OBJECT (ptr), "realize",
578 G_CALLBACK (realize_cb), obj);
580 gdk_threads_leave ();
583 JNIEXPORT void JNICALL
584 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
585 (JNIEnv *env, jobject obj)
587 struct graphics2d *gr = NULL;
589 gdk_threads_enter();
590 gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
591 if (gr == NULL)
593 gdk_threads_leave();
594 return; /* dispose has been called more than once */
597 if (gr->surface)
598 cairo_surface_destroy (gr->surface);
600 cairo_destroy (gr->cr);
602 if (gr->drawbuf)
603 g_object_unref (gr->drawbuf);
605 g_object_unref (gr->drawable);
607 if (gr->pattern)
608 cairo_pattern_destroy (gr->pattern);
610 if (gr->pattern_surface)
611 cairo_surface_destroy (gr->pattern_surface);
613 if (gr->pattern_pixels)
614 free (gr->pattern_pixels);
616 if (gr->mode == MODE_JAVA_ARRAY)
617 (*env)->DeleteGlobalRef(env, gr->jarray);
619 if (gr->debug) printf ("disposed of graphics2d\n");
621 free (gr);
622 gdk_threads_leave();
626 JNIEXPORT void JNICALL
627 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient
628 (JNIEnv *env, jobject obj,
629 jdouble x1, jdouble y1,
630 jdouble x2, jdouble y2,
631 jint r1, jint g1, jint b1, jint a1,
632 jint r2, jint g2, jint b2, jint a2,
633 jboolean cyclic)
635 struct graphics2d *gr = NULL;
636 cairo_surface_t *surf = NULL;
637 cairo_matrix_t *mat = NULL;
638 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
639 g_assert (gr != NULL);
641 gdk_threads_enter();
642 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
643 if (gr->debug) printf ("setGradient (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
644 x1, y1,
645 x2, y2,
646 r1, g1, b1, a1,
647 r2, g2, b2, a2);
649 cairo_save (gr->cr);
651 if (cyclic)
652 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2);
653 else
654 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2);
655 g_assert (surf != NULL);
657 cairo_set_target_surface (gr->cr, surf);
659 cairo_identity_matrix (gr->cr);
661 cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0);
662 cairo_set_alpha (gr->cr, a1 / 255.0);
663 cairo_rectangle (gr->cr, 0, 0, 1, 2);
664 cairo_fill (gr->cr);
666 cairo_set_rgb_color (gr->cr, r2 / 255.0, g2 / 255.0, b2 / 255.0);
667 cairo_set_alpha (gr->cr, a2 / 255.0);
668 cairo_rectangle (gr->cr, 1, 0, 1, 2);
669 cairo_fill (gr->cr);
671 if (cyclic)
673 cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0);
674 cairo_set_alpha (gr->cr, a1 / 255.0);
675 cairo_rectangle (gr->cr, 2, 0, 1, 2);
676 cairo_fill (gr->cr);
679 mat = cairo_matrix_create ();
680 g_assert (mat != NULL);
683 consider the vector [x2 - x1, y2 - y1] = [p,q]
685 this is a line in space starting at an 'origin' x1, y1.
687 it can also be thought of as a "transformed" unit vector in either the
688 x or y directions. we have just *drawn* our gradient as a unit vector
689 (well, a 2-3x unit vector) in the x dimension. so what we want to know
690 is which transformation turns our existing unit vector into [p,q].
692 which means solving for M in
694 [p,q] = M[1,0]
696 [p,q] = |a b| [1,0]
697 |c d|
699 [p,q] = [a,c], with b = d = 0.
701 what does this mean? it means that our gradient is 1-dimensional; as
702 you move through the x axis of our 2 or 3 pixel gradient from logical
703 x positions 0 to 1, the transformation of your x coordinate under the
704 matrix M causes you to accumulate both x and y values in fill
705 space. the y value of a gradient coordinate is ignored, since the
706 gradient is one dimensional. which is correct.
708 unfortunately we want the opposite transformation, it seems, because of
709 the way cairo is going to use this transformation. I'm a bit confused by
710 that, but it seems to work right, so we take reciprocals of values and
711 negate offsets. oh well.
715 double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
716 double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
717 double dx = (x1 == 0.) ? 0. : 1. / x1;
718 double dy = (y1 == 0.) ? 0. : 1. / y1;
720 cairo_matrix_set_affine (mat,
721 a, 0.,
722 c, 0.,
723 dx, dy);
725 cairo_surface_set_matrix (surf, mat);
726 cairo_matrix_destroy (mat);
727 cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
730 /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
731 /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
733 if (gr->pattern)
734 cairo_pattern_destroy (gr->pattern);
736 if (gr->pattern_surface)
737 cairo_surface_destroy (gr->pattern_surface);
739 if (gr->pattern_pixels)
740 free (gr->pattern_pixels);
742 gr->pattern_pixels = NULL;
743 gr->pattern_surface = surf;
744 gr->pattern = cairo_pattern_create_for_surface(surf);
746 cairo_restore (gr->cr);
747 cairo_set_pattern (gr->cr, gr->pattern);
748 gdk_threads_leave();
751 JNIEXPORT void JNICALL
752 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
753 (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
755 struct graphics2d *gr = NULL;
756 jint *jpixels = NULL;
758 gdk_threads_enter();
759 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
760 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
761 g_assert (gr != NULL);
763 if (gr->debug) printf ("setTexturePixels (%d pixels, %dx%d, stride: %d)\n",
764 (*env)->GetArrayLength (env, jarr), w, h, stride);
766 if (gr->pattern)
767 cairo_pattern_destroy (gr->pattern);
769 if (gr->pattern_surface)
770 cairo_surface_destroy (gr->pattern_surface);
772 if (gr->pattern_pixels)
773 free (gr->pattern_pixels);
775 gr->pattern = NULL;
776 gr->pattern_surface = NULL;
777 gr->pattern_pixels = NULL;
779 gr->pattern_pixels = (char *) malloc (h * stride * 4);
780 g_assert (gr->pattern_pixels != NULL);
782 jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
783 g_assert (jpixels != NULL);
784 memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
785 (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
787 gr->pattern_surface = cairo_surface_create_for_image (gr->pattern_pixels,
788 CAIRO_FORMAT_ARGB32,
789 w, h, stride * 4);
790 g_assert (gr->pattern_surface != NULL);
791 cairo_surface_set_repeat (gr->pattern_surface, 1);
792 gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
793 g_assert (gr->pattern != NULL);
794 cairo_set_pattern (gr->cr, gr->pattern);
795 gdk_threads_leave();
798 JNIEXPORT void JNICALL
799 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
800 (JNIEnv *env, jobject obj, jintArray java_pixels,
801 jint w, jint h, jint stride, jdoubleArray java_matrix)
803 struct graphics2d *gr = NULL;
804 jint *native_pixels = NULL;
805 jdouble *native_matrix = NULL;
807 gdk_threads_enter();
808 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
810 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
811 g_assert (gr != NULL);
813 if (gr->debug) printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
814 (*env)->GetArrayLength (env, java_pixels), w, h, stride);
816 native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
817 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
818 g_assert (native_pixels != NULL);
819 g_assert (native_matrix != NULL);
820 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
822 begin_drawing_operation (env, gr);
825 cairo_matrix_t *mat = NULL;
826 cairo_surface_t *surf = cairo_surface_create_for_image ((char *)native_pixels,
827 CAIRO_FORMAT_ARGB32,
828 w, h, stride * 4);
829 mat = cairo_matrix_create ();
830 cairo_matrix_set_affine (mat,
831 native_matrix[0], native_matrix[1],
832 native_matrix[2], native_matrix[3],
833 native_matrix[4], native_matrix[5]);
834 cairo_surface_set_matrix (surf, mat);
835 cairo_surface_set_filter (surf, cairo_surface_get_filter(gr->surface));
836 cairo_show_surface (gr->cr, surf, w, h);
837 cairo_matrix_destroy (mat);
838 cairo_surface_destroy (surf);
841 end_drawing_operation (env, gr);
843 (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
844 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
846 gdk_threads_leave();
849 /* passthrough methods to cairo */
851 JNIEXPORT void JNICALL
852 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave
853 (JNIEnv *env, jobject obj)
855 struct graphics2d *gr = NULL;
857 gdk_threads_enter();
858 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
860 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
861 g_assert (gr != NULL);
862 if (gr->debug) printf ("cairo_save\n");
863 cairo_save (gr->cr);
864 gdk_threads_leave();
867 JNIEXPORT void JNICALL
868 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
869 (JNIEnv *env, jobject obj)
871 struct graphics2d *gr = NULL;
873 gdk_threads_enter();
874 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
876 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
877 g_assert (gr != NULL);
878 if (gr->debug) printf ("cairo_restore\n");
879 cairo_restore (gr->cr);
880 update_pattern_transform (gr);
881 gdk_threads_leave();
884 JNIEXPORT void JNICALL
885 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
886 (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
888 struct graphics2d *gr = NULL;
889 jdouble *native_matrix = NULL;
891 gdk_threads_enter();
892 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
894 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
895 /* cairoSetMatrix was called before this graphics object's component
896 was realized. */
897 if (gr == NULL) { gdk_threads_leave (); return; }
899 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
900 g_assert (native_matrix != NULL);
901 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
903 if (gr->debug) printf ("cairo_set_matrix [ %f, %f, %f, %f, %f, %f ]\n",
904 native_matrix[0], native_matrix[1],
905 native_matrix[2], native_matrix[3],
906 native_matrix[4], native_matrix[5]);
909 cairo_matrix_t * mat = cairo_matrix_create ();
910 cairo_matrix_set_affine (mat,
911 native_matrix[0], native_matrix[1],
912 native_matrix[2], native_matrix[3],
913 native_matrix[4], native_matrix[5]);
914 cairo_set_matrix (gr->cr, mat);
915 cairo_matrix_destroy (mat);
918 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
919 update_pattern_transform (gr);
920 gdk_threads_leave();
923 static void
924 install_font_peer(cairo_t *cr,
925 struct peerfont *pfont,
926 int debug)
928 cairo_font_t *ft;
929 FT_Face face = NULL;
931 g_assert(cr != NULL);
932 g_assert(pfont != NULL);
934 if (pfont->graphics_resource == NULL)
936 face = pango_ft2_font_get_face (pfont->font);
937 g_assert (face != NULL);
939 ft = cairo_ft_font_create_for_ft_face (face);
940 g_assert (ft != NULL);
942 if (debug) printf ("install_font_peer made new cairo font for '%s' at %f\n",
943 face->family_name,
944 (pango_font_description_get_size (pfont->desc) /
945 (double)PANGO_SCALE));
947 cairo_set_font (cr, ft);
948 cairo_font_destroy (ft);
949 cairo_scale_font (cr,
950 (pango_font_description_get_size (pfont->desc) /
951 (double)PANGO_SCALE));
952 ft = cairo_current_font (cr);
953 pfont->graphics_resource = ft;
955 else
957 if (debug) printf ("install_font_peer reused existing font resource\n");
958 ft = (cairo_font_t *) pfont->graphics_resource;
959 cairo_set_font (cr, ft);
964 JNIEXPORT void JNICALL
965 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
966 (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font)
968 struct peerfont *pfont = NULL;
970 g_assert(java_font != NULL);
972 gdk_threads_enter();
973 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
974 g_assert (pfont != NULL);
975 if (pfont->graphics_resource != NULL)
977 cairo_font_destroy ((cairo_font_t *) pfont->graphics_resource);
978 pfont->graphics_resource = NULL;
980 gdk_threads_leave();
983 static void
984 paint_glyph_run(JNIEnv *env,
985 struct graphics2d *gr,
986 cairo_glyph_t **glyphs,
987 gint *n_glyphs,
988 PangoLayoutRun *run)
990 gint i = 0;
991 gint x = 0, y = 0;
993 g_assert (gr != NULL);
994 g_assert (glyphs != NULL);
995 g_assert (n_glyphs != NULL);
996 g_assert (run != NULL);
998 if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
1000 if (*n_glyphs < run->glyphs->num_glyphs)
1002 *glyphs = g_realloc(*glyphs,
1003 (sizeof(cairo_glyph_t)
1004 * run->glyphs->num_glyphs));
1005 *n_glyphs = run->glyphs->num_glyphs;
1008 g_assert (*glyphs != NULL);
1010 if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs);
1012 for (i = 0; i < run->glyphs->num_glyphs; ++i)
1014 (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
1016 (*glyphs)[i].x =
1017 ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
1018 / ((double) PANGO_SCALE);
1020 (*glyphs)[i].y =
1021 ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
1022 / ((double) PANGO_SCALE);
1024 if (gr->debug) printf(" (%ld @ %f,%f)",
1025 (*glyphs)[i].index,
1026 (*glyphs)[i].x,
1027 (*glyphs)[i].y);
1029 x += run->glyphs->glyphs[i].geometry.width;
1032 if (gr->debug) printf("\n");
1033 begin_drawing_operation (env, gr);
1034 cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs);
1035 end_drawing_operation (env, gr);
1040 JNIEXPORT void JNICALL
1041 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGlyphVector
1042 (JNIEnv *env, jobject self,
1043 jobject font,
1044 jfloat x, jfloat y, jint n,
1045 jintArray java_codes,
1046 jfloatArray java_positions)
1049 struct graphics2d *gr = NULL;
1050 struct peerfont *pfont = NULL;
1051 cairo_glyph_t *glyphs = NULL;
1052 int *native_codes;
1053 float *native_positions;
1054 jint i = 0;
1056 g_assert (self != NULL);
1057 g_assert (java_codes != NULL);
1058 g_assert (java_positions != NULL);
1060 gdk_threads_enter ();
1061 if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; }
1063 gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
1064 g_assert (gr != NULL);
1066 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
1067 g_assert (pfont != NULL);
1069 install_font_peer(gr->cr, pfont, gr->debug);
1071 glyphs = malloc( sizeof(cairo_glyph_t) * n);
1072 g_assert (glyphs != NULL);
1074 native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
1075 native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL);
1077 for (i = 0; i < n; ++i)
1079 glyphs[i].index = native_codes[i];
1080 glyphs[i].x = x + native_positions[ 2*i ];
1081 glyphs[i].y = y + native_positions[ 2*i + 1];
1084 (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0);
1085 (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
1087 begin_drawing_operation (env, gr);
1088 cairo_show_glyphs (gr->cr, glyphs, n);
1089 end_drawing_operation (env, gr);
1091 gdk_threads_leave ();
1092 free(glyphs);
1095 JNIEXPORT void JNICALL
1096 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout
1097 (JNIEnv *env, jobject self, jobject java_layout, jfloat x, jfloat y)
1100 * FIXME: Some day we expect either cairo or pango will know how to make
1101 * a pango layout paint to a cairo surface. that day is not yet here.
1104 struct graphics2d *gr = NULL;
1105 struct textlayout *tl = NULL;
1106 PangoLayoutIter *i = NULL;
1107 PangoLayoutRun *run = NULL;
1108 cairo_glyph_t *glyphs = NULL;
1109 gint n_glyphs = 0;
1111 g_assert (self != NULL);
1112 g_assert (java_layout != NULL);
1114 gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
1115 tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout);
1117 g_assert (gr != NULL);
1118 g_assert (tl != NULL);
1119 g_assert (tl->pango_layout != NULL);
1121 if (gr->debug) printf ("painting pango layout\n");
1123 gdk_threads_enter ();
1124 if (peer_is_disposed(env, self)) { gdk_threads_leave(); return; }
1126 i = pango_layout_get_iter (tl->pango_layout);
1127 g_assert (i != NULL);
1129 cairo_translate (gr->cr, x, y);
1133 run = pango_layout_iter_get_run (i);
1134 if (run != NULL)
1135 paint_glyph_run (env, gr, &glyphs, &n_glyphs, run);
1137 while (pango_layout_iter_next_run (i));
1139 if (glyphs != NULL)
1140 g_free (glyphs);
1142 cairo_translate (gr->cr, -x, -y);
1144 pango_layout_iter_free (i);
1145 gdk_threads_leave ();
1148 JNIEXPORT void JNICALL
1149 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
1150 (JNIEnv *env, jobject obj, jint op)
1152 struct graphics2d *gr = NULL;
1154 gdk_threads_enter();
1155 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1157 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1158 g_assert (gr != NULL);
1159 if (gr->debug) printf ("cairo_set_operator %d\n", op);
1160 switch ((enum java_awt_alpha_composite_rule) op)
1162 case java_awt_alpha_composite_CLEAR:
1163 cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
1164 break;
1166 case java_awt_alpha_composite_SRC:
1167 cairo_set_operator (gr->cr, CAIRO_OPERATOR_SRC);
1168 break;
1170 case java_awt_alpha_composite_SRC_OVER:
1171 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
1172 break;
1174 case java_awt_alpha_composite_DST_OVER:
1175 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER_REVERSE);
1176 break;
1178 case java_awt_alpha_composite_SRC_IN:
1179 cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
1180 break;
1182 case java_awt_alpha_composite_DST_IN:
1183 cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN_REVERSE);
1184 break;
1186 case java_awt_alpha_composite_SRC_OUT:
1187 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
1188 break;
1190 case java_awt_alpha_composite_DST_OUT:
1191 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT_REVERSE);
1192 break;
1194 case java_awt_alpha_composite_DST:
1195 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DST);
1196 break;
1198 case java_awt_alpha_composite_SRC_ATOP:
1199 cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
1200 break;
1202 case java_awt_alpha_composite_DST_ATOP:
1203 cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP_REVERSE);
1204 break;
1206 case java_awt_alpha_composite_XOR:
1207 cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
1208 break;
1210 gdk_threads_leave();
1213 JNIEXPORT void JNICALL
1214 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBColor
1215 (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b)
1217 struct graphics2d *gr = NULL;
1219 gdk_threads_enter();
1220 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1222 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1223 g_assert (gr != NULL);
1225 /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider
1226 colors in opposite pixel order. I have no idea why. thus when you
1227 draw to a PixBuf, you must exchange the R and B components of your
1228 color. */
1230 if (gr->debug) printf ("cairo_set_rgb_color (%f, %f, %f)\n", r, g, b);
1232 if (gr->drawbuf)
1233 cairo_set_rgb_color (gr->cr, b, g, r);
1234 else
1235 cairo_set_rgb_color (gr->cr, r, g, b);
1237 gdk_threads_leave();
1240 JNIEXPORT void JNICALL
1241 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetAlpha
1242 (JNIEnv *env, jobject obj, jdouble a)
1244 struct graphics2d *gr = NULL;
1246 gdk_threads_enter();
1247 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1249 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1250 g_assert (gr != NULL);
1251 if (gr->debug) printf ("cairo_set_alpha %f\n", a);
1252 cairo_set_alpha (gr->cr, a);
1253 gdk_threads_leave();
1256 JNIEXPORT void JNICALL
1257 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule
1258 (JNIEnv *env, jobject obj, jint rule)
1260 struct graphics2d *gr = NULL;
1262 gdk_threads_enter();
1263 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1265 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1266 if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
1267 g_assert (gr != NULL);
1268 switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
1270 case java_awt_geom_path_iterator_WIND_NON_ZERO:
1271 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
1272 break;
1273 case java_awt_geom_path_iterator_WIND_EVEN_ODD:
1274 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
1275 break;
1277 gdk_threads_leave();
1280 JNIEXPORT void JNICALL
1281 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth
1282 (JNIEnv *env, jobject obj, jdouble width)
1284 struct graphics2d *gr = NULL;
1286 gdk_threads_enter();
1287 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1289 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1290 g_assert (gr != NULL);
1291 if (gr->debug) printf ("cairo_set_line_width %f\n", width);
1292 cairo_set_line_width (gr->cr, width);
1293 gdk_threads_leave();
1296 JNIEXPORT void JNICALL
1297 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap
1298 (JNIEnv *env, jobject obj, jint cap)
1300 struct graphics2d *gr = NULL;
1302 gdk_threads_enter();
1303 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1305 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1306 g_assert (gr != NULL);
1307 if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
1308 switch ((enum java_awt_basic_stroke_cap_rule) cap)
1310 case java_awt_basic_stroke_CAP_BUTT:
1311 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
1312 break;
1314 case java_awt_basic_stroke_CAP_ROUND:
1315 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
1316 break;
1318 case java_awt_basic_stroke_CAP_SQUARE:
1319 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
1320 break;
1322 gdk_threads_leave();
1325 JNIEXPORT void JNICALL
1326 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin
1327 (JNIEnv *env, jobject obj, jint join)
1329 struct graphics2d *gr = NULL;
1331 gdk_threads_enter();
1332 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1334 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1335 g_assert (gr != NULL);
1336 if (gr->debug) printf ("cairo_set_line_join %d\n", join);
1337 switch ((enum java_awt_basic_stroke_join_rule) join)
1339 case java_awt_basic_stroke_JOIN_MITER:
1340 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
1341 break;
1343 case java_awt_basic_stroke_JOIN_ROUND:
1344 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
1345 break;
1347 case java_awt_basic_stroke_JOIN_BEVEL:
1348 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
1349 break;
1351 gdk_threads_leave();
1354 JNIEXPORT void JNICALL
1355 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash
1356 (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
1358 struct graphics2d *gr = NULL;
1359 jdouble *dasharr = NULL;
1361 gdk_threads_enter();
1362 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1364 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1365 g_assert (gr != NULL);
1366 if (gr->debug) printf ("cairo_set_dash\n");
1367 dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
1368 g_assert (dasharr != NULL);
1369 cairo_set_dash (gr->cr, dasharr, ndash, offset);
1370 (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
1371 gdk_threads_leave();
1374 JNIEXPORT void JNICALL
1375 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit
1376 (JNIEnv *env, jobject obj, jdouble miter)
1378 struct graphics2d *gr = NULL;
1380 gdk_threads_enter();
1381 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1383 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1384 g_assert (gr != NULL);
1385 if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
1386 cairo_set_miter_limit (gr->cr, miter);
1387 gdk_threads_leave();
1391 JNIEXPORT void JNICALL
1392 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath
1393 (JNIEnv *env, jobject obj)
1395 struct graphics2d *gr = NULL;
1397 gdk_threads_enter();
1398 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1400 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1401 if (gr == NULL) { gdk_threads_leave (); return; }
1402 if (gr->debug) printf ("cairo_new_path\n");
1403 cairo_new_path (gr->cr);
1404 gdk_threads_leave();
1407 JNIEXPORT void JNICALL
1408 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo
1409 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
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_move_to (%f, %f)\n", x, y);
1419 cairo_move_to (gr->cr, x, y);
1420 gdk_threads_leave();
1423 JNIEXPORT void JNICALL
1424 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo
1425 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
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_line_to (%f, %f)\n", x, y);
1435 cairo_line_to (gr->cr, x, y);
1436 gdk_threads_leave();
1439 JNIEXPORT void JNICALL
1440 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo
1441 (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
1443 struct graphics2d *gr = NULL;
1445 gdk_threads_enter();
1446 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1448 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1449 g_assert (gr != NULL);
1450 if (gr->debug) printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n", x1, y1, x2, y2, x3, y3);
1451 cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
1452 gdk_threads_leave();
1455 JNIEXPORT void JNICALL
1456 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo
1457 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1459 struct graphics2d *gr = NULL;
1461 gdk_threads_enter();
1462 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1464 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1465 g_assert (gr != NULL);
1466 if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
1467 cairo_rel_move_to (gr->cr, dx, dy);
1468 gdk_threads_leave();
1471 JNIEXPORT void JNICALL
1472 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo
1473 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1475 struct graphics2d *gr = NULL;
1477 gdk_threads_enter();
1478 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1480 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1481 g_assert (gr != NULL);
1482 if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
1483 cairo_rel_line_to (gr->cr, dx, dy);
1484 gdk_threads_leave();
1487 JNIEXPORT void JNICALL
1488 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo
1489 (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
1491 struct graphics2d *gr = NULL;
1493 gdk_threads_enter();
1494 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1496 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1497 g_assert (gr != NULL);
1498 if (gr->debug) printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n", dx1, dy1, dx2, dy2, dx3, dy3);
1499 cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
1500 gdk_threads_leave();
1503 JNIEXPORT void JNICALL
1504 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle
1505 (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
1507 struct graphics2d *gr = NULL;
1509 gdk_threads_enter();
1510 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1512 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1513 if (gr == NULL) { gdk_threads_leave (); return; }
1514 if (gr->debug) printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
1515 cairo_rectangle (gr->cr, x, y, width, height);
1516 gdk_threads_leave();
1519 JNIEXPORT void JNICALL
1520 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath
1521 (JNIEnv *env, jobject obj)
1523 struct graphics2d *gr = NULL;
1525 gdk_threads_enter();
1526 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1528 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1529 g_assert (gr != NULL);
1530 if (gr->debug) printf ("cairo_close_path\n");
1531 cairo_close_path (gr->cr);
1532 gdk_threads_leave();
1535 JNIEXPORT void JNICALL
1536 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
1537 (JNIEnv *env, jobject obj)
1539 struct graphics2d *gr = NULL;
1541 gdk_threads_enter();
1542 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1544 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1545 g_assert (gr != NULL);
1546 if (gr->debug) printf ("cairo_stroke\n");
1547 begin_drawing_operation (env, gr);
1548 cairo_stroke (gr->cr);
1549 end_drawing_operation (env, gr);
1550 gdk_threads_leave();
1553 JNIEXPORT void JNICALL
1554 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
1555 (JNIEnv *env, jobject obj)
1557 struct graphics2d *gr = NULL;
1559 gdk_threads_enter();
1560 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1562 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1563 g_assert (gr != NULL);
1564 if (gr->debug) printf ("cairo_fill\n");
1565 begin_drawing_operation (env, gr);
1566 cairo_fill (gr->cr);
1567 end_drawing_operation (env, gr);
1568 gdk_threads_leave();
1571 JNIEXPORT void JNICALL
1572 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
1573 (JNIEnv *env, jobject obj)
1575 struct graphics2d *gr = NULL;
1577 gdk_threads_enter();
1578 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1580 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1581 if (gr == NULL) { gdk_threads_leave (); return; }
1582 if (gr->debug) printf ("cairo_clip\n");
1583 begin_drawing_operation (env, gr);
1584 cairo_init_clip (gr->cr);
1585 cairo_clip (gr->cr);
1586 end_drawing_operation (env, gr);
1587 gdk_threads_leave();
1590 JNIEXPORT void JNICALL
1591 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
1592 (JNIEnv *env, jobject obj, jint filter)
1594 struct graphics2d *gr = NULL;
1596 gdk_threads_enter();
1597 if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; }
1599 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1600 g_assert (gr != NULL);
1601 if (gr->debug) printf ("cairo_surface_set_filter %d\n", filter);
1602 switch ((enum java_awt_rendering_hints_filter) filter)
1604 case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
1605 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
1606 break;
1607 case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
1608 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BILINEAR);
1609 break;
1610 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
1611 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
1612 break;
1613 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
1614 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
1615 break;
1616 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
1617 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BEST);
1618 break;
1620 gdk_threads_leave();