1 /* gnu_java_awt_peer_gtk_GdkGraphics2d.c
2 Copyright (C) 2003 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 Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState
68 (JNIEnv *env, jclass clazz)
70 NSA_G2D_INIT (env, clazz);
73 /* these public final constants are part of the java2d public API, so we
74 write them explicitly here to save fetching them from the constant pool
78 #define min(x,y) ((x) < (y) ? (x) : (y))
81 enum java_awt_alpha_composite_rule
83 java_awt_alpha_composite_CLEAR = 1,
84 java_awt_alpha_composite_SRC = 2,
85 java_awt_alpha_composite_SRC_OVER = 3,
86 java_awt_alpha_composite_DST_OVER = 4,
87 java_awt_alpha_composite_SRC_IN = 5,
88 java_awt_alpha_composite_DST_IN = 6,
89 java_awt_alpha_composite_SRC_OUT = 7,
90 java_awt_alpha_composite_DST_OUT = 8,
91 java_awt_alpha_composite_DST = 9,
92 java_awt_alpha_composite_SRC_ATOP = 10,
93 java_awt_alpha_composite_DST_ATOP = 11,
94 java_awt_alpha_composite_XOR = 12
97 enum java_awt_basic_stroke_join_rule
99 java_awt_basic_stroke_JOIN_MITER = 0,
100 java_awt_basic_stroke_JOIN_ROUND = 1,
101 java_awt_basic_stroke_JOIN_BEVEL = 2
104 enum java_awt_basic_stroke_cap_rule
106 java_awt_basic_stroke_CAP_BUTT = 0,
107 java_awt_basic_stroke_CAP_ROUND = 1,
108 java_awt_basic_stroke_CAP_SQUARE = 2
111 enum java_awt_geom_path_iterator_winding_rule
113 java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
114 java_awt_geom_path_iterator_WIND_NON_ZERO = 1
117 enum java_awt_rendering_hints_filter
119 java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
120 java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
121 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
122 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
123 java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
128 grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
130 g_assert (widget != NULL);
131 g_assert (draw != NULL);
132 g_assert (win != NULL);
134 if (GTK_IS_WINDOW (widget))
136 *win = find_gtk_layout (widget)->bin_window;
138 else if (GTK_IS_LAYOUT (widget))
140 *win = GTK_LAYOUT (widget)->bin_window;
144 *win = widget->window;
148 gdk_window_get_internal_paint_info (*win, draw, 0, 0);
149 g_object_ref (*draw);
154 x_server_has_render_extension (void)
157 return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
162 init_graphics2d_as_pixbuf (struct graphics2d *gr)
165 gint bits_per_sample = 8;
166 gint total_channels = 4;
167 gboolean has_alpha = TRUE;
169 g_assert (gr != NULL);
170 g_assert (gr->drawable != NULL);
172 if (gr->debug) printf ("initializing graphics2d as pixbuf\n");
173 gdk_drawable_get_size (gr->drawable, &width, &height);
174 gr->drawbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
175 has_alpha, bits_per_sample,
177 g_assert (gr->drawbuf != NULL);
178 g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample);
179 g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels);
181 gr->surface = cairo_surface_create_for_image (gdk_pixbuf_get_pixels (gr->drawbuf),
183 gdk_pixbuf_get_width (gr->drawbuf),
184 gdk_pixbuf_get_height (gr->drawbuf),
185 gdk_pixbuf_get_rowstride (gr->drawbuf));
186 g_assert (gr->surface != NULL);
187 g_assert (gr->cr != NULL);
188 cairo_set_target_surface (gr->cr, gr->surface);
192 init_graphics2d_as_renderable (struct graphics2d *gr)
198 g_assert (gr != NULL);
199 g_assert (gr->drawable != NULL);
203 if (gr->debug) printf ("initializing graphics2d as renderable\n");
204 draw = gdk_x11_drawable_get_xid (gr->drawable);
206 dpy = gdk_x11_drawable_get_xdisplay (gr->drawable);
207 g_assert (dpy != NULL);
209 vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
210 g_assert (vis != NULL);
212 gr->surface = cairo_xlib_surface_create (dpy, draw, vis,
214 DefaultColormap (dpy, DefaultScreen (dpy)));
215 g_assert (gr->surface != NULL);
216 g_assert (gr->cr != NULL);
217 cairo_set_target_surface (gr->cr, gr->surface);
221 begin_drawing_operation (struct graphics2d * gr)
223 gdk_threads_enter ();
227 gint drawable_width, drawable_height;
228 gint pixbuf_width, pixbuf_height;
231 gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
232 pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
233 pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
234 width = min (drawable_width, pixbuf_width);
235 height = min (drawable_height, pixbuf_height);
237 gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
243 if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
249 end_drawing_operation (struct graphics2d * gr)
253 gint drawable_width, drawable_height;
254 gint pixbuf_width, pixbuf_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_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
266 GDK_RGB_DITHER_NORMAL, 0, 0);
268 if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
271 gdk_threads_leave ();
276 update_pattern_transform (struct graphics2d *gr)
278 double a, b, c, d, tx, ty;
279 cairo_matrix_t *mat = NULL;
281 g_assert (gr != NULL);
282 if (gr->pattern == NULL)
286 /* temporarily disabled: ambiguous behavior */
287 /* cairo_get_matrix (gr->cr, &a, &b, &c, &d, &tx, &ty); */
288 mat = cairo_matrix_create ();
289 g_assert (mat != NULL);
290 cairo_matrix_set_affine (mat, a, b, c, d, tx, ty);
291 cairo_surface_set_matrix (gr->pattern, mat);
292 cairo_matrix_destroy (mat);
296 check_for_debug (struct graphics2d *gr)
298 gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL);
301 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
302 (JNIEnv *env, jobject obj, jobject old)
304 struct graphics2d *g = NULL, *g_old = NULL;
306 g = (struct graphics2d *) malloc (sizeof (struct graphics2d));
307 g_assert (g != NULL);
308 memset (g, 0, sizeof(struct graphics2d));
310 g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
311 g_assert (g_old != NULL);
313 if (g_old->debug) printf ("copying state from existing graphics2d\n");
315 g->drawable = g_old->drawable;
316 g->debug = g_old->debug;
318 gdk_threads_enter ();
319 g_object_ref (g->drawable);
321 g->cr = cairo_create();
322 g_assert (g->cr != NULL);
324 if (x_server_has_render_extension ())
325 init_graphics2d_as_renderable (g);
327 init_graphics2d_as_pixbuf (g);
329 cairo_surface_set_filter (g->surface, CAIRO_FILTER_FAST);
331 gdk_threads_leave ();
333 NSA_SET_G2D_PTR (env, obj, g);
337 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
338 (JNIEnv *env, jobject obj, jint width, jint height)
340 struct graphics2d *gr;
342 gdk_threads_enter ();
344 gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
345 g_assert (gr != NULL);
346 memset (gr, 0, sizeof(struct graphics2d));
348 check_for_debug (gr);
350 if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
353 gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
354 gdk_rgb_get_visual ()->depth);
355 g_assert (gr->drawable != NULL);
357 gr->cr = cairo_create();
358 g_assert (gr->cr != NULL);
360 if (x_server_has_render_extension ())
361 init_graphics2d_as_renderable (gr);
363 init_graphics2d_as_pixbuf (gr);
365 gdk_threads_leave ();
366 if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
368 NSA_SET_G2D_PTR (env, obj, gr);
371 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
372 (JNIEnv *env, jobject self, jobject other, jint x, jint y)
374 struct graphics2d *src = NULL, *dst = NULL;
375 gint s_height, s_width, d_height, d_width, height, width;
378 src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
379 dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self);
380 g_assert (src != NULL);
381 g_assert (dst != NULL);
383 if (src->debug) printf ("copying from offscreen drawable\n");
385 gdk_threads_enter ();
386 gdk_drawable_get_size (src->drawable, &s_width, &s_height);
387 gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
388 width = min (s_width, d_width);
389 height = min (s_width, d_height);
391 gc = gdk_gc_new (dst->drawable);
392 g_assert (gc != NULL);
394 gdk_draw_drawable(dst->drawable, gc, src->drawable,
395 0, 0, x, y, width, height);
400 if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
401 gdk_threads_leave ();
405 current_colors_of_widget (GtkWidget *widget, JNIEnv *env)
411 g_assert (widget != NULL);
412 g_assert (env != NULL);
414 color = widget->style->fg[GTK_STATE_NORMAL];
415 array = (*env)->NewIntArray (env, 6);
417 rgb = (*env)->GetIntArrayElements (env, array, NULL);
418 rgb[0] = color.red >> 8;
419 rgb[1] = color.green >> 8;
420 rgb[2] = color.blue >> 8;
422 color = widget->style->bg[GTK_STATE_NORMAL];
423 rgb[3] = color.red >> 8;
424 rgb[4] = color.green >> 8;
425 rgb[5] = color.blue >> 8;
427 (*env)->ReleaseIntArrayElements (env, array, rgb, 0);
432 JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
433 (JNIEnv *env, jobject obj, jobject peer)
435 struct graphics2d *gr = NULL;
436 GtkWidget *widget = NULL;
440 ptr = NSA_GET_PTR (env, peer);
441 g_assert (ptr != NULL);
442 gdk_threads_enter ();
444 gr = (struct graphics2d *) malloc (sizeof (struct graphics2d));
445 g_assert (gr != NULL);
446 memset (gr, 0, sizeof(struct graphics2d));
448 check_for_debug (gr);
450 gr->cr = cairo_create();
451 g_assert (gr->cr != NULL);
453 widget = GTK_WIDGET (ptr);
454 g_assert (widget != NULL);
456 grab_current_drawable (widget, &(gr->drawable), &(gr->win));
457 g_assert (gr->drawable != NULL);
459 if (x_server_has_render_extension ())
460 init_graphics2d_as_renderable (gr);
462 init_graphics2d_as_pixbuf (gr);
464 color = current_colors_of_widget (widget, env);
466 gdk_threads_leave ();
467 NSA_SET_G2D_PTR (env, obj, gr);
471 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
472 (JNIEnv *env, jobject obj)
474 struct graphics2d *gr = NULL;
476 gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
478 return; /* dispose has been called more than once */
480 gdk_threads_enter ();
483 cairo_surface_destroy (gr->surface);
485 cairo_destroy (gr->cr);
488 g_object_unref (gr->drawbuf);
490 g_object_unref (gr->drawable);
493 cairo_surface_destroy (gr->pattern);
495 if (gr->pattern_pixels)
496 free (gr->pattern_pixels);
498 if (gr->debug) printf ("disposed of graphics2d\n");
501 gdk_threads_leave ();
505 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient
506 (JNIEnv *env, jobject obj,
507 jdouble x1, jdouble y1,
508 jdouble x2, jdouble y2,
509 jint r1, jint g1, jint b1, jint a1,
510 jint r2, jint g2, jint b2, jint a2,
513 struct graphics2d *gr = NULL;
514 cairo_surface_t *surf = NULL;
515 cairo_matrix_t *mat = NULL;
516 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
517 g_assert (gr != NULL);
519 if (gr->debug) printf ("setGradient (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
528 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2);
530 surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2);
531 g_assert (surf != NULL);
533 cairo_set_target_surface (gr->cr, surf);
535 cairo_identity_matrix (gr->cr);
537 cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0);
538 cairo_set_alpha (gr->cr, a1 / 255.0);
539 cairo_rectangle (gr->cr, 0, 0, 1, 2);
542 cairo_set_rgb_color (gr->cr, r2 / 255.0, g2 / 255.0, b2 / 255.0);
543 cairo_set_alpha (gr->cr, a2 / 255.0);
544 cairo_rectangle (gr->cr, 1, 0, 1, 2);
549 cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0);
550 cairo_set_alpha (gr->cr, a1 / 255.0);
551 cairo_rectangle (gr->cr, 2, 0, 1, 2);
555 mat = cairo_matrix_create ();
556 g_assert (mat != NULL);
559 consider the vector [x2 - x1, y2 - y1] = [p,q]
561 this is a line in space starting at an 'origin' x1, y1.
563 it can also be thought of as a "transformed" unit vector in either the
564 x or y directions. we have just *drawn* our gradient as a unit vector
565 (well, a 2-3x unit vector) in the x dimension. so what we want to know
566 is which transformation turns our existing unit vector into [p,q].
568 which means solving for M in
575 [p,q] = [a,c], with b = d = 0.
577 what does this mean? it means that our gradient is 1-dimensional; as
578 you move through the x axis of our 2 or 3 pixel gradient from logical
579 x positions 0 to 1, the transformation of your x coordinate under the
580 matrix M causes you to accumulate both x and y values in fill
581 space. the y value of a gradient coordinate is ignored, since the
582 gradient is one dimensional. which is correct.
584 unfortunately we want the opposite transformation, it seems, because of
585 the way cairo is going to use this transformation. I'm a bit confused by
586 that, but it seems to work right, so we take reciprocals of values and
587 negate offsets. oh well.
591 double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
592 double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
593 double dx = (x1 == 0.) ? 0. : 1. / x1;
594 double dy = (y1 == 0.) ? 0. : 1. / y1;
596 cairo_matrix_set_affine (mat,
601 cairo_surface_set_matrix (surf, mat);
602 cairo_matrix_destroy (mat);
603 cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
605 /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
606 /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
609 cairo_surface_destroy (gr->pattern);
611 if (gr->pattern_pixels)
613 free (gr->pattern_pixels);
614 gr->pattern_pixels = NULL;
619 cairo_restore (gr->cr);
620 cairo_set_pattern (gr->cr, gr->pattern);
624 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
625 (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
627 struct graphics2d *gr = NULL;
628 jint *jpixels = NULL;
630 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
631 g_assert (gr != NULL);
633 if (gr->debug) printf ("setTexturePixels (%d pixels, %dx%d, stride: %d)\n",
634 (*env)->GetArrayLength (env, jarr), w, h, stride);
637 cairo_surface_destroy (gr->pattern);
639 if (gr->pattern_pixels)
640 free (gr->pattern_pixels);
643 gr->pattern_pixels = NULL;
645 gr->pattern_pixels = (char *) malloc (h * stride * 4);
646 g_assert (gr->pattern_pixels != NULL);
648 jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
649 g_assert (jpixels != NULL);
650 memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
651 (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
653 gr->pattern = cairo_surface_create_for_image (gr->pattern_pixels,
656 g_assert (gr->pattern != NULL);
657 cairo_surface_set_repeat (gr->pattern, 1);
658 cairo_set_pattern (gr->cr, gr->pattern);
662 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
663 (JNIEnv *env, jobject obj, jintArray java_pixels,
664 jint w, jint h, jint stride, jdoubleArray java_matrix)
666 struct graphics2d *gr = NULL;
667 jint *native_pixels = NULL;
668 jdouble *native_matrix = NULL;
670 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
671 g_assert (gr != NULL);
673 if (gr->debug) printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
674 (*env)->GetArrayLength (env, java_pixels), w, h, stride);
676 native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
677 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
678 g_assert (native_pixels != NULL);
679 g_assert (native_matrix != NULL);
680 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
682 begin_drawing_operation (gr);
685 cairo_matrix_t *mat = NULL;
686 cairo_surface_t *surf = cairo_surface_create_for_image ((char *)native_pixels,
689 mat = cairo_matrix_create ();
690 cairo_matrix_set_affine (mat,
691 native_matrix[0], native_matrix[1],
692 native_matrix[2], native_matrix[3],
693 native_matrix[4], native_matrix[5]);
694 cairo_surface_set_matrix (surf, mat);
695 cairo_surface_set_filter (surf, cairo_surface_get_filter(gr->surface));
696 cairo_show_surface (gr->cr, surf, w, h);
697 cairo_matrix_destroy (mat);
698 cairo_surface_destroy (surf);
701 end_drawing_operation (gr);
703 (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
704 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
708 JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getImagePixels
709 (JNIEnv *env, jobject obj)
711 struct graphics2d *gr = NULL;
712 jintArray java_pixels;
714 GdkPixbuf *buf = NULL;
716 gint bits_per_sample = 8;
717 gboolean has_alpha = TRUE;
718 gint total_channels = 4;
721 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
722 g_assert (gr != NULL);
724 if (gr->debug) printf ("getImagePixels\n");
726 gdk_drawable_get_size (gr->drawable, &width, &height);
728 buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha,
731 g_assert (buf != NULL);
732 g_assert (gdk_pixbuf_get_bits_per_sample (buf) == bits_per_sample);
733 g_assert (gdk_pixbuf_get_n_channels (buf) == total_channels);
736 /* copy pixels from drawable to pixbuf */
738 gdk_pixbuf_get_from_drawable (buf, gr->drawable,
743 native_pixels= gdk_pixbuf_get_pixels (buf);
746 /* NOTE: The pixels we got in the pixbuf are stored
747 in reversed order. i.e 0xBBGGRRAA.
748 We need to convert them to 0xAARRGGBB. */
750 for (i=0; i<width * height; i++)
753 /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
755 px = native_pixels[i];
756 px = ((px >> 24) & 0xff) | ((px << 8) & 0xffffff00);
757 px = ((px >> 8) & 0x00ff00ff) | ((px << 8) & 0xff00ff00);
758 px = ((px >> 16) & 0x0000ffff) | ((px << 16) & 0xffff0000);
759 native_pixels[i] = px;
763 java_pixels = (*env) -> NewIntArray (env, width * height);
765 (*env)->SetIntArrayRegion(env, java_pixels,
766 (jsize)0, (jsize) width*height,
767 (jint*) native_pixels);
773 /* passthrough methods to cairo */
775 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave
776 (JNIEnv *env, jobject obj)
778 struct graphics2d *gr = NULL;
779 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
780 g_assert (gr != NULL);
781 if (gr->debug) printf ("cairo_save\n");
785 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
786 (JNIEnv *env, jobject obj)
788 struct graphics2d *gr = NULL;
789 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
790 g_assert (gr != NULL);
791 if (gr->debug) printf ("cairo_restore\n");
792 cairo_restore (gr->cr);
793 update_pattern_transform (gr);
796 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
797 (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
799 struct graphics2d *gr = NULL;
800 jdouble *native_matrix = NULL;
802 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
803 g_assert (gr != NULL);
805 native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
806 g_assert (native_matrix != NULL);
807 g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
809 if (gr->debug) printf ("cairo_set_matrix [ %f, %f, %f, %f, %f, %f ]\n",
810 native_matrix[0], native_matrix[1],
811 native_matrix[2], native_matrix[3],
812 native_matrix[4], native_matrix[5]);
815 cairo_matrix_t * mat = cairo_matrix_create ();
816 cairo_matrix_set_affine (mat,
817 native_matrix[0], native_matrix[1],
818 native_matrix[2], native_matrix[3],
819 native_matrix[4], native_matrix[5]);
820 cairo_set_matrix (gr->cr, mat);
821 cairo_matrix_destroy (mat);
824 (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
825 update_pattern_transform (gr);
828 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFont
829 (JNIEnv *env, jobject obj, jobject font)
831 struct graphics2d *gr = NULL;
832 struct peerfont *pfont = NULL;
833 cairo_font_t *ft = NULL;
836 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
837 g_assert (gr != NULL);
839 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
840 g_assert (pfont != NULL);
842 gdk_threads_enter ();
844 face = pango_ft2_font_get_face (pfont->font);
845 g_assert (face != NULL);
847 ft = cairo_ft_font_create_for_ft_face (face);
848 g_assert (ft != NULL);
850 if (gr->debug) printf ("cairo_set_font '%s'\n", face->family_name);
852 cairo_set_font (gr->cr, ft);
854 cairo_scale_font (gr->cr,
855 pango_font_description_get_size (pfont->desc) /
856 (double)PANGO_SCALE);
858 cairo_font_destroy (ft);
860 gdk_threads_leave ();
863 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoShowGlyphs
864 (JNIEnv *env, jobject obj, jintArray java_codes, jfloatArray java_posns)
866 struct graphics2d *gr = NULL;
867 cairo_glyph_t *glyphs = NULL;
868 jfloat *native_posns = NULL;
869 jint *native_codes = NULL;
873 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
874 g_assert (gr != NULL);
876 native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
877 native_posns = (*env)->GetFloatArrayElements (env, java_posns, NULL);
878 g_assert (native_codes != NULL);
879 g_assert (native_posns != NULL);
881 ncodes = (*env)->GetArrayLength (env, java_codes);
882 nposns = (*env)->GetArrayLength (env, java_posns);
883 g_assert (2 * ncodes == nposns);
885 if (gr->debug) printf ("cairo_show_glyphs (%d glyphs)\n", ncodes);
887 glyphs = malloc (sizeof(cairo_glyph_t) * ncodes);
890 for (i = 0; i < ncodes; ++i)
892 glyphs[i].index = native_codes[i];
893 glyphs[i].x = (double) native_posns[2*i];
894 glyphs[i].y = (double) native_posns[2*i + 1];
895 if (gr->debug) printf ("cairo_show_glyphs (glyph %d (code %d) : %f,%f)\n",
896 i, glyphs[i].index, glyphs[i].x, glyphs[i].y);
899 (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
900 (*env)->ReleaseFloatArrayElements (env, java_posns, native_posns, 0);
902 begin_drawing_operation (gr);
903 cairo_show_glyphs (gr->cr, glyphs, ncodes);
904 end_drawing_operation (gr);
909 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
910 (JNIEnv *env, jobject obj, jint op)
912 struct graphics2d *gr = NULL;
913 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
914 g_assert (gr != NULL);
915 if (gr->debug) printf ("cairo_set_operator %d\n", op);
916 switch ((enum java_awt_alpha_composite_rule) op)
918 case java_awt_alpha_composite_CLEAR:
919 cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
922 case java_awt_alpha_composite_SRC:
923 cairo_set_operator (gr->cr, CAIRO_OPERATOR_SRC);
926 case java_awt_alpha_composite_SRC_OVER:
927 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
930 case java_awt_alpha_composite_DST_OVER:
931 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER_REVERSE);
934 case java_awt_alpha_composite_SRC_IN:
935 cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
938 case java_awt_alpha_composite_DST_IN:
939 cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN_REVERSE);
942 case java_awt_alpha_composite_SRC_OUT:
943 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
946 case java_awt_alpha_composite_DST_OUT:
947 cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT_REVERSE);
950 case java_awt_alpha_composite_DST:
951 cairo_set_operator (gr->cr, CAIRO_OPERATOR_DST);
954 case java_awt_alpha_composite_SRC_ATOP:
955 cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
958 case java_awt_alpha_composite_DST_ATOP:
959 cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP_REVERSE);
962 case java_awt_alpha_composite_XOR:
963 cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
968 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBColor
969 (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b)
971 struct graphics2d *gr = NULL;
972 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
973 g_assert (gr != NULL);
975 /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider
976 colors in opposite pixel order. I have no idea why. thus when you
977 draw to a PixBuf, you must exchange the R and B components of your
980 if (gr->debug) printf ("cairo_set_rgb_color (%f, %f, %f)\n", r, g, b);
983 cairo_set_rgb_color (gr->cr, b, g, r);
985 cairo_set_rgb_color (gr->cr, r, g, b);
988 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetAlpha
989 (JNIEnv *env, jobject obj, jdouble a)
991 struct graphics2d *gr = NULL;
992 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
993 g_assert (gr != NULL);
994 if (gr->debug) printf ("cairo_set_alpha %f\n", a);
995 cairo_set_alpha (gr->cr, a);
998 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule
999 (JNIEnv *env, jobject obj, jint rule)
1001 struct graphics2d *gr = NULL;
1002 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1003 if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
1004 g_assert (gr != NULL);
1005 switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
1007 case java_awt_geom_path_iterator_WIND_NON_ZERO:
1008 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
1010 case java_awt_geom_path_iterator_WIND_EVEN_ODD:
1011 cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
1016 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth
1017 (JNIEnv *env, jobject obj, jdouble width)
1019 struct graphics2d *gr = NULL;
1020 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1021 g_assert (gr != NULL);
1022 if (gr->debug) printf ("cairo_set_line_width %f\n", width);
1023 cairo_set_line_width (gr->cr, width);
1026 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap
1027 (JNIEnv *env, jobject obj, jint cap)
1029 struct graphics2d *gr = NULL;
1030 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1031 g_assert (gr != NULL);
1032 if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
1033 switch ((enum java_awt_basic_stroke_cap_rule) cap)
1035 case java_awt_basic_stroke_CAP_BUTT:
1036 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
1039 case java_awt_basic_stroke_CAP_ROUND:
1040 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
1043 case java_awt_basic_stroke_CAP_SQUARE:
1044 cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
1049 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin
1050 (JNIEnv *env, jobject obj, jint join)
1052 struct graphics2d *gr = NULL;
1053 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1054 g_assert (gr != NULL);
1055 if (gr->debug) printf ("cairo_set_line_join %d\n", join);
1056 switch ((enum java_awt_basic_stroke_join_rule) join)
1058 case java_awt_basic_stroke_JOIN_MITER:
1059 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
1062 case java_awt_basic_stroke_JOIN_ROUND:
1063 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
1066 case java_awt_basic_stroke_JOIN_BEVEL:
1067 cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
1072 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash
1073 (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
1075 struct graphics2d *gr = NULL;
1076 jdouble *dasharr = NULL;
1077 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1078 g_assert (gr != NULL);
1079 if (gr->debug) printf ("cairo_set_dash\n");
1080 dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
1081 g_assert (dasharr != NULL);
1082 cairo_set_dash (gr->cr, dasharr, ndash, offset);
1083 (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
1086 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit
1087 (JNIEnv *env, jobject obj, jdouble miter)
1089 struct graphics2d *gr = NULL;
1090 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1091 g_assert (gr != NULL);
1092 if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
1093 cairo_set_miter_limit (gr->cr, miter);
1097 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath
1098 (JNIEnv *env, jobject obj)
1100 struct graphics2d *gr = NULL;
1101 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1102 g_assert (gr != NULL);
1103 if (gr->debug) printf ("cairo_new_path\n");
1104 cairo_new_path (gr->cr);
1107 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo
1108 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
1110 struct graphics2d *gr = NULL;
1111 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1112 g_assert (gr != NULL);
1113 if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y);
1114 cairo_move_to (gr->cr, x, y);
1117 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo
1118 (JNIEnv *env, jobject obj, jdouble x, jdouble y)
1120 struct graphics2d *gr = NULL;
1121 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1122 g_assert (gr != NULL);
1123 if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y);
1124 cairo_line_to (gr->cr, x, y);
1127 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo
1128 (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
1130 struct graphics2d *gr = NULL;
1131 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1132 g_assert (gr != NULL);
1133 if (gr->debug) printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n", x1, y1, x2, y2, x3, y3);
1134 cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
1137 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo
1138 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1140 struct graphics2d *gr = NULL;
1141 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1142 g_assert (gr != NULL);
1143 if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
1144 cairo_rel_move_to (gr->cr, dx, dy);
1147 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo
1148 (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
1150 struct graphics2d *gr = NULL;
1151 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1152 g_assert (gr != NULL);
1153 if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
1154 cairo_rel_line_to (gr->cr, dx, dy);
1157 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo
1158 (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
1160 struct graphics2d *gr = NULL;
1161 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1162 g_assert (gr != NULL);
1163 if (gr->debug) printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n", dx1, dy1, dx2, dy2, dx3, dy3);
1164 cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
1167 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle
1168 (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
1170 struct graphics2d *gr = NULL;
1171 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1172 g_assert (gr != NULL);
1173 if (gr->debug) printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
1174 cairo_rectangle (gr->cr, x, y, width, height);
1177 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath
1178 (JNIEnv *env, jobject obj)
1180 struct graphics2d *gr = NULL;
1181 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1182 g_assert (gr != NULL);
1183 if (gr->debug) printf ("cairo_close_path\n");
1184 cairo_close_path (gr->cr);
1187 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
1188 (JNIEnv *env, jobject obj)
1190 struct graphics2d *gr = NULL;
1191 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1192 g_assert (gr != NULL);
1193 if (gr->debug) printf ("cairo_stroke\n");
1194 begin_drawing_operation (gr);
1195 cairo_stroke (gr->cr);
1196 end_drawing_operation (gr);
1199 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
1200 (JNIEnv *env, jobject obj)
1202 struct graphics2d *gr = NULL;
1203 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1204 g_assert (gr != NULL);
1205 if (gr->debug) printf ("cairo_fill\n");
1206 begin_drawing_operation (gr);
1207 cairo_fill (gr->cr);
1208 end_drawing_operation (gr);
1211 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
1212 (JNIEnv *env, jobject obj)
1214 struct graphics2d *gr = NULL;
1215 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1216 g_assert (gr != NULL);
1217 if (gr->debug) printf ("cairo_clip\n");
1218 cairo_clip (gr->cr);
1221 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
1222 (JNIEnv *env, jobject obj, jint filter)
1225 struct graphics2d *gr = NULL;
1226 gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
1227 g_assert (gr != NULL);
1228 if (gr->debug) printf ("cairo_surface_set_filter %d\n", filter);
1229 switch ((enum java_awt_rendering_hints_filter) filter)
1231 case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
1232 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
1234 case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
1235 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BILINEAR);
1237 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
1238 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
1240 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
1241 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_NEAREST);
1243 case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
1244 cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BEST);