diff options
Diffstat (limited to 'native/jni/gtk-peer')
19 files changed, 2034 insertions, 3288 deletions
diff --git a/native/jni/gtk-peer/Makefile.am b/native/jni/gtk-peer/Makefile.am index 9c373cb4d..a4013cf37 100644 --- a/native/jni/gtk-peer/Makefile.am +++ b/native/jni/gtk-peer/Makefile.am @@ -1,17 +1,12 @@ nativeexeclib_LTLIBRARIES = libgtkpeer.la -# Gtk/Cairo JNI sources. -if GTK_CAIRO - gtk_cairo_c_source_files = \ - gnu_java_awt_peer_gtk_GdkGraphics2D.c -else - gtk_cairo_c_source_files = -endif - -libgtkpeer_la_SOURCES = $(gtk_cairo_c_source_files) \ +# GTK JNI sources. +libgtkpeer_la_SOURCES = gnu_java_awt_peer_gtk_CairoSurface.c \ + gnu_java_awt_peer_gtk_CairoGraphics2D.c \ + gnu_java_awt_peer_gtk_ComponentGraphics.c \ + gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c \ gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \ gnu_java_awt_peer_gtk_GdkFontPeer.c \ - gnu_java_awt_peer_gtk_GdkGraphics.c \ gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c \ gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \ gnu_java_awt_peer_gtk_GdkRobotPeer.c \ @@ -44,22 +39,23 @@ libgtkpeer_la_SOURCES = $(gtk_cairo_c_source_files) \ gnu_java_awt_peer_gtk_GtkTextFieldPeer.c \ gnu_java_awt_peer_gtk_GtkToolkit.c \ gnu_java_awt_peer_gtk_GtkWindowPeer.c \ + gnu_java_awt_peer_gtk_GtkVolatileImage.c \ + cairographics2d.h \ gthread-jni.c \ gdkfont.h \ gthread-jni.h \ - gtkcairopeer.h \ gtk_jawt.c \ gtkpeer.h libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo \ $(top_builddir)/native/jni/classpath/jcl.lo -AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @CAIRO_LIBS@ @FREETYPE2_LIBS@ \ - @PANGOFT2_LIBS@ @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ -lX11 -lXtst +AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @FREETYPE2_LIBS@ \ + @PANGOFT2_LIBS@ @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ @XTEST_LIBS@ AM_CPPFLAGS = @CLASSPATH_INCLUDES@ # Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk # headers contain broken prototypes (by design, see gtkitemfactory.h). AM_CFLAGS = @WARNING_CFLAGS@ @ERROR_CFLAGS@ \ - @GTK_CFLAGS@ @CAIRO_CFLAGS@ @FREETYPE2_CFLAGS@ @PANGOFT2_CFLAGS@ \ + @GTK_CFLAGS@ @FREETYPE2_CFLAGS@ @PANGOFT2_CFLAGS@ \ @X_CFLAGS@ diff --git a/native/jni/gtk-peer/cairographics2d.h b/native/jni/gtk-peer/cairographics2d.h new file mode 100644 index 000000000..2c12384de --- /dev/null +++ b/native/jni/gtk-peer/cairographics2d.h @@ -0,0 +1,119 @@ +/* cairographics2d.h -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#ifndef CAIROGRAPHICS2D_H +#define CAIROGRAPHICS2D_H + + +#include <cairo.h> +#include <gtk/gtk.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <config.h> +#include "native_state.h" +#include <gdk-pixbuf/gdk-pixbuf.h> + +#include <jni.h> + +/* + * These public final constants are part of the java2d public API, so we + * write them explicitly here to save fetching them from the constant pool + * all the time. + */ +enum java_awt_alpha_composite_rule + { + java_awt_alpha_composite_CLEAR = 1, + java_awt_alpha_composite_SRC = 2, + java_awt_alpha_composite_SRC_OVER = 3, + java_awt_alpha_composite_DST_OVER = 4, + java_awt_alpha_composite_SRC_IN = 5, + java_awt_alpha_composite_DST_IN = 6, + java_awt_alpha_composite_SRC_OUT = 7, + java_awt_alpha_composite_DST_OUT = 8, + java_awt_alpha_composite_DST = 9, + java_awt_alpha_composite_SRC_ATOP = 10, + java_awt_alpha_composite_DST_ATOP = 11, + java_awt_alpha_composite_XOR = 12 + }; + +enum java_awt_basic_stroke_join_rule + { + java_awt_basic_stroke_JOIN_MITER = 0, + java_awt_basic_stroke_JOIN_ROUND = 1, + java_awt_basic_stroke_JOIN_BEVEL = 2 + }; + +enum java_awt_basic_stroke_cap_rule + { + java_awt_basic_stroke_CAP_BUTT = 0, + java_awt_basic_stroke_CAP_ROUND = 1, + java_awt_basic_stroke_CAP_SQUARE = 2 + }; + +enum java_awt_geom_path_iterator_winding_rule + { + java_awt_geom_path_iterator_WIND_EVEN_ODD = 0, + java_awt_geom_path_iterator_WIND_NON_ZERO = 1 + }; + +enum java_awt_rendering_hints_filter + { + java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0, + java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1, + java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2, + java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3, + java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4 + + }; + +/** + * A structure which basically contains the cairo_t pointer. + * The rest is for gradient and texture fills. + */ +struct cairographics2d +{ + cairo_t *cr; + cairo_surface_t *pattern_surface; + cairo_pattern_t *pattern; + char *pattern_pixels; +}; + +cairo_t *cp_gtk_get_cairo_t(JNIEnv *env, + jobject cairographics2dobj); + +#endif diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c new file mode 100644 index 000000000..1cc8b8caa --- /dev/null +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c @@ -0,0 +1,699 @@ +/* gnu_java_awt_peer_gtk_CairoGraphics2d.c + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include "jcl.h" +#include "gdkfont.h" +#include "cairographics2d.h" +#include "gnu_java_awt_peer_gtk_CairoGraphics2D.h" +#include <gdk/gdktypes.h> +#include <gdk/gdkprivate.h> +#include <gdk/gdkx.h> + +#include <cairo-ft.h> +#include <cairo-xlib.h> + +#include <stdio.h> +#include <stdlib.h> + +static void install_font_peer(cairo_t *cr, struct peerfont *pfont); +static void update_pattern_transform (struct cairographics2d *gr); +static struct cairographics2d *getPointer(JNIEnv *env, jobject obj); + +static struct cairographics2d * +getPointer(JNIEnv *env, jobject obj) +{ + jclass cls; + jlong value; + jfieldID nofid; + cls = (*env)->GetObjectClass( env, obj ); + nofid = (*env)->GetFieldID( env, cls, "nativePointer", "J" ); + value = (*env)->GetLongField( env, obj, nofid ); + (*env)->DeleteLocalRef( env, cls ); + + return JLONG_TO_PTR(struct cairographics2d, value); +} + +/** + * Returns the cairo_t * associated with a CairoGraphics2D object, + * This is used by GdkTextLayout. + */ +cairo_t *cp_gtk_get_cairo_t(JNIEnv *env, + jobject cairographics2dobj) +{ + struct cairographics2d *gr = getPointer(env, cairographics2dobj); + g_assert(gr != NULL); + return gr->cr; +} + +/** + * Allocates the cairographics2d structure. + */ +JNIEXPORT jlong JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_init + (JNIEnv *env __attribute__ ((unused)), + jobject obj __attribute__ ((unused)), + jlong cairo_t_pointer) +{ + struct cairographics2d *g = NULL; + cairo_t *cr = JLONG_TO_PTR(cairo_t, cairo_t_pointer); + g_assert(cr != NULL); + + g = (struct cairographics2d *) g_malloc (sizeof (struct cairographics2d)); + + g_assert (g != NULL); + memset (g, 0, sizeof(struct cairographics2d)); + g->cr = cr; + + return PTR_TO_JLONG(g); +} + +/** + * Disposes of the cairographics2d structure. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_disposeNative + (JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer(env, obj); + + if (gr == NULL) + return; + + if (gr->cr) + cairo_destroy (gr->cr); + + if (gr->pattern) + cairo_pattern_destroy (gr->pattern); + gr->pattern = NULL; + + if (gr->pattern_surface) + cairo_surface_destroy (gr->pattern_surface); + gr->pattern_surface = NULL; + + g_free( gr ); +} + +/** + * Set the gradient. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setGradient + (JNIEnv *env, jobject obj, + jdouble x1, jdouble y1, + jdouble x2, jdouble y2, + jint r1, jint g1, jint b1, jint a1, + jint r2, jint g2, jint b2, jint a2, + jboolean cyclic) +{ + struct cairographics2d *gr = NULL; + cairo_pattern_t* pattern; + cairo_extend_t extend; + + gr = getPointer (env, obj); + g_assert( gr != NULL ); + + pattern = cairo_pattern_create_linear(x1, y1, x2, y2); + g_assert( pattern != NULL ); + + cairo_pattern_add_color_stop_rgba(pattern, 0.0, r1 / 255.0, g1 / 255.0, + b1 / 255.0, a1 / 255.0); + + cairo_pattern_add_color_stop_rgba(pattern, 1.0, r2 / 255.0, g2 / 255.0, + b2 / 255.0, a2 / 255.0); + + extend = (cyclic == JNI_TRUE) ? CAIRO_EXTEND_REFLECT : CAIRO_EXTEND_NONE; + + cairo_pattern_set_extend( pattern, extend ); + + gr->pattern = pattern; + cairo_set_source(gr->cr, gr->pattern); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setTexturePixels + (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride) +{ + struct cairographics2d *gr = NULL; + jint *jpixels = NULL; + + gr = getPointer (env, obj); + g_assert (gr != NULL); + + if (gr->pattern) + cairo_pattern_destroy (gr->pattern); + + if (gr->pattern_surface) + cairo_surface_destroy (gr->pattern_surface); + + if (gr->pattern_pixels) + g_free (gr->pattern_pixels); + + gr->pattern = NULL; + gr->pattern_surface = NULL; + gr->pattern_pixels = NULL; + + gr->pattern_pixels = (char *) g_malloc (h * stride * 4); + g_assert (gr->pattern_pixels != NULL); + + jpixels = (*env)->GetIntArrayElements (env, jarr, NULL); + g_assert (jpixels != NULL); + memcpy (gr->pattern_pixels, jpixels, h * stride * 4); + (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0); + + gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels, + CAIRO_FORMAT_ARGB32, + w, h, stride * 4); + g_assert (gr->pattern_surface != NULL); + gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface); + g_assert (gr->pattern != NULL); + cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT); + cairo_set_source (gr->cr, gr->pattern); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_drawPixels + (JNIEnv *env, jobject obj, jintArray java_pixels, + jint w, jint h, jint stride, jdoubleArray java_matrix) +{ + jint *native_pixels = NULL; + jdouble *native_matrix = NULL; + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL); + native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL); + g_assert (native_pixels != NULL); + g_assert (native_matrix != NULL); + g_assert ((*env)->GetArrayLength (env, java_matrix) == 6); + + { + cairo_matrix_t mat; + cairo_pattern_t *p; + cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels, + CAIRO_FORMAT_ARGB32, + w, h, stride * 4); + cairo_matrix_init_identity (&mat); + cairo_matrix_init (&mat, + native_matrix[0], native_matrix[1], + native_matrix[2], native_matrix[3], + native_matrix[4], native_matrix[5]); + + p = cairo_pattern_create_for_surface (surf); + cairo_pattern_set_matrix (p, &mat); + if (gr->pattern) + cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern)); + cairo_set_source (gr->cr, p); + cairo_paint (gr->cr); + cairo_pattern_destroy (p); + cairo_surface_destroy (surf); + } + + (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0); + (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0); +} + + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetMatrix + (JNIEnv *env, jobject obj, jdoubleArray java_matrix) +{ + jdouble *native_matrix = NULL; + struct cairographics2d *gr = getPointer (env, obj); + + native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL); + g_assert (native_matrix != NULL); + g_assert ((*env)->GetArrayLength (env, java_matrix) == 6); + + { + cairo_matrix_t mat; + + cairo_matrix_init_identity (&mat); + cairo_matrix_init (&mat, + native_matrix[0], native_matrix[1], + native_matrix[2], native_matrix[3], + native_matrix[4], native_matrix[5]); + cairo_set_matrix (gr->cr, &mat); + } + + (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0); + update_pattern_transform (gr); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawGlyphVector + (JNIEnv *env, jobject obj, + jobject font, + jfloat x, jfloat y, jint n, + jintArray java_codes, + jfloatArray java_positions) +{ + + struct cairographics2d *gr = NULL; + struct peerfont *pfont = NULL; + cairo_glyph_t *glyphs = NULL; + int *native_codes; + float *native_positions; + jint i = 0; + + g_assert (obj != NULL); + g_assert (java_codes != NULL); + g_assert (java_positions != NULL); + + gr = getPointer (env, obj); + g_assert (gr != NULL); + + pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font); + g_assert (pfont != NULL); + + install_font_peer(gr->cr, pfont); + + glyphs = g_malloc( sizeof(cairo_glyph_t) * n); + g_assert (glyphs != NULL); + + native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL); + native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL); + + for (i = 0; i < n; ++i) + { + glyphs[i].index = native_codes[i]; + glyphs[i].x = x + native_positions[ 2*i ]; + glyphs[i].y = y + native_positions[ 2*i + 1]; + } + + (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0); + (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0); + + cairo_show_glyphs (gr->cr, glyphs, n); + + g_free(glyphs); +} + + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetOperator + (JNIEnv *env, jobject obj, jint op) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + switch ((enum java_awt_alpha_composite_rule) op) + { + case java_awt_alpha_composite_CLEAR: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR); + break; + + case java_awt_alpha_composite_SRC: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE); + break; + + case java_awt_alpha_composite_SRC_OVER: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER); + break; + + case java_awt_alpha_composite_DST_OVER: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER); + break; + + case java_awt_alpha_composite_SRC_IN: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN); + break; + + case java_awt_alpha_composite_DST_IN: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN); + break; + + case java_awt_alpha_composite_SRC_OUT: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT); + break; + + case java_awt_alpha_composite_DST_OUT: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT); + break; + + case java_awt_alpha_composite_DST: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST); + break; + + case java_awt_alpha_composite_SRC_ATOP: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP); + break; + + case java_awt_alpha_composite_DST_ATOP: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP); + break; + + case java_awt_alpha_composite_XOR: + cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR); + break; + } +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetRGBAColor + (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_set_source_rgba (gr->cr, r, g, b, a); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetFillRule + (JNIEnv *env, jobject obj, jint rule) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + switch ((enum java_awt_geom_path_iterator_winding_rule) rule) + { + case java_awt_geom_path_iterator_WIND_NON_ZERO: + cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING); + break; + case java_awt_geom_path_iterator_WIND_EVEN_ODD: + cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD); + break; + } +} + +/** + * Set the line style, except for dashes. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetLine + (JNIEnv *env, jobject obj, jdouble width, int cap, int join, double miterLimit) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + /* set width */ + cairo_set_line_width (gr->cr, width); + + /* set cap */ + switch ((enum java_awt_basic_stroke_cap_rule) cap) + { + case java_awt_basic_stroke_CAP_BUTT: + cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT); + break; + + case java_awt_basic_stroke_CAP_ROUND: + cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND); + break; + + case java_awt_basic_stroke_CAP_SQUARE: + cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE); + break; + } + + /* set join */ + switch ((enum java_awt_basic_stroke_join_rule) join) + { + case java_awt_basic_stroke_JOIN_MITER: + cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER); + break; + + case java_awt_basic_stroke_JOIN_ROUND: + cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND); + break; + + case java_awt_basic_stroke_JOIN_BEVEL: + cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL); + break; + } + + /* set miter */ + cairo_set_miter_limit (gr->cr, miterLimit); +} + +/** + * Set the line dashes + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetDash + (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset) +{ + jdouble *dasharr = NULL; + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL); + g_assert (dasharr != NULL); + + cairo_set_dash (gr->cr, dasharr, ndash, offset); + + (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoNewPath + (JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_new_path (gr->cr); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoMoveTo + (JNIEnv *env, jobject obj, jdouble x, jdouble y) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_move_to (gr->cr, x, y); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoLineTo + (JNIEnv *env, jobject obj, jdouble x, jdouble y) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_line_to (gr->cr, x, y); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoCurveTo + (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelMoveTo + (JNIEnv *env, jobject obj, jdouble dx, jdouble dy) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_rel_move_to (gr->cr, dx, dy); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelLineTo + (JNIEnv *env, jobject obj, jdouble dx, jdouble dy) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_rel_line_to (gr->cr, dx, dy); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelCurveTo + (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRectangle + (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height) +{ + struct cairographics2d *gr = getPointer (env, obj); + + cairo_rectangle (gr->cr, x, y, width, height); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClosePath + (JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_close_path (gr->cr); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoStroke + (JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_stroke (gr->cr); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoFill + (JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + cairo_fill (gr->cr); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClip + (JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer( env, obj ); + g_assert( gr != NULL ); + + cairo_clip( gr->cr ); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoResetClip + (JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer( env, obj ); + g_assert (gr != NULL); + + cairo_reset_clip( gr->cr ); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoPreserveClip +(JNIEnv *env, jobject obj) +{ + struct cairographics2d *gr = getPointer( env, obj ); + g_assert (gr != NULL); + + cairo_clip_preserve( gr->cr ); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSurfaceSetFilter + (JNIEnv *env, jobject obj, jint filter) +{ + struct cairographics2d *gr = getPointer (env, obj); + g_assert (gr != NULL); + + if (gr->pattern == NULL) + return; + + switch ((enum java_awt_rendering_hints_filter) filter) + { + case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR: + cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST); + break; + case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR: + cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR); + break; + case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED: + cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST); + break; + case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT: + cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST); + break; + case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY: + cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST); + break; + } +} + +/************************** FONT STUFF ****************************/ +static void +install_font_peer(cairo_t *cr, + struct peerfont *pfont) +{ + cairo_font_face_t *ft; + FT_Face face = NULL; + + g_assert(cr != NULL); + g_assert(pfont != NULL); + + if (pfont->graphics_resource == NULL) + { + face = pango_ft2_font_get_face (pfont->font); + g_assert (face != NULL); + + ft = cairo_ft_font_face_create_for_ft_face (face, 0); + g_assert (ft != NULL); + + cairo_set_font_face (cr, ft); + cairo_font_face_destroy (ft); + cairo_set_font_size (cr, + (pango_font_description_get_size (pfont->desc) / + (double)PANGO_SCALE)); + ft = cairo_get_font_face (cr); + pfont->graphics_resource = ft; + } + else + { + ft = (cairo_font_face_t *) pfont->graphics_resource; + cairo_set_font_face (cr, ft); + cairo_set_font_size (cr, + (pango_font_description_get_size (pfont->desc) / + (double)PANGO_SCALE)); + } +} + +static void +update_pattern_transform (struct cairographics2d *gr) +{ + cairo_matrix_t mat; + + g_assert (gr != NULL); + if (gr->pattern == NULL) + return; + + cairo_get_matrix (gr->cr, &mat); + cairo_pattern_set_matrix (gr->pattern, &mat); +} + + diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c new file mode 100644 index 000000000..1a618cef5 --- /dev/null +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c @@ -0,0 +1,311 @@ +/* gnu_java_awt_peer_gtk_CairoSurface.c + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include "jcl.h" +#include "gtkpeer.h" +#include <cairo-xlib.h> +#include <gdk/gdkx.h> + +#include "gnu_java_awt_peer_gtk_CairoSurface.h" +#include "cairographics2d.h" + +/** + * Field names in CairoSurface.java + */ +#define SURFACE "surfacePointer" +#define BUFFER "bufferPointer" + +/* prototypes */ +static void *getNativeObject( JNIEnv *env, jobject obj, const char *pointer ); +static void setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer ); + +/** + * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject obj, jint width, jint height, jint stride) +{ + cairo_surface_t* surface; + void *data = g_malloc(stride * height * 4); + memset(data, 0, stride * height * 4); + setNativeObject(env, obj, data, BUFFER); + + surface = cairo_image_surface_create_for_data + (data, CAIRO_FORMAT_ARGB32, width, height, stride); + + setNativeObject(env, obj, surface, SURFACE); +} + +/** + * Destroy the surface + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_destroy (JNIEnv *env, jobject obj) +{ + void *buffer; + cairo_surface_t* surface = (cairo_surface_t *)getNativeObject(env, obj, SURFACE); + if( surface != NULL ) + cairo_surface_destroy(surface); + + buffer = getNativeObject(env, obj, BUFFER); + if( buffer != NULL ) + g_free(buffer); +} + +/** + * Gets a pixel + */ +JNIEXPORT jint JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem (JNIEnv *env, jobject obj, jint i) +{ + jint *pixeldata = (jint *)getNativeObject(env, obj, BUFFER); + + if( pixeldata == NULL ) + return 0; + + return pixeldata[i]; +} + +/** + * Sets a pixel + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem +(JNIEnv *env, jobject obj, jint i, jint val) +{ + jint *pixeldata = (jint *)getNativeObject(env, obj, BUFFER); + + if( pixeldata == NULL ) + return; + + pixeldata[i] = val; +} + +/** + * Gets all pixels in an array + */ +JNIEXPORT jintArray JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_getPixels +(JNIEnv *env, jobject obj, int size) +{ + jint *pixeldata, *jpixdata; + jintArray jpixels; + + pixeldata = (jint *)getNativeObject(env, obj, BUFFER); + g_assert(pixeldata != NULL); + + jpixels = (*env)->NewIntArray (env, size); + jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL); + memcpy (jpixdata, pixeldata, size * sizeof( jint )); + + (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0); + return jpixels; +} + +/** + * Sets all pixels by an array. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_setPixels +(JNIEnv *env, jobject obj, jintArray jpixels) +{ + jint *pixeldata, *jpixdata; + int size; + int width, height; + jclass cls; + jfieldID field; + + if( jpixels == NULL ) + return; + + cls = (*env)->GetObjectClass (env, obj); + field = (*env)->GetFieldID (env, cls, "width", "I"); + g_assert (field != 0); + width = (*env)->GetIntField (env, obj, field); + + field = (*env)->GetFieldID (env, cls, "height", "I"); + g_assert (field != 0); + height = (*env)->GetIntField (env, obj, field); + + pixeldata = (jint *)getNativeObject(env, obj, BUFFER); + g_assert(pixeldata != NULL); + + jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL); + size = (*env)->GetArrayLength( env, jpixels ); + if( size > width * height ) size = width * height; /* stop overflows. */ + + memcpy (pixeldata, jpixdata, size * sizeof( jint )); + + (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_drawSurface + (JNIEnv *env, jobject obj, jobject context, jdoubleArray java_matrix) +{ + cairo_t *cr; + jdouble *native_matrix = NULL; + cairo_surface_t* surface = (cairo_surface_t *)getNativeObject(env, obj, SURFACE); + g_assert(surface != NULL); + + cr = cp_gtk_get_cairo_t(env, context); + g_assert(cr != NULL); + + native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL); + g_assert (native_matrix != NULL); + g_assert ((*env)->GetArrayLength (env, java_matrix) == 6); + + { + cairo_matrix_t mat; + cairo_pattern_t *p; + cairo_matrix_init_identity (&mat); + cairo_matrix_init (&mat, + native_matrix[0], native_matrix[1], + native_matrix[2], native_matrix[3], + native_matrix[4], native_matrix[5]); + + p = cairo_pattern_create_for_surface (surface); + cairo_pattern_set_matrix (p, &mat); + + cairo_set_source(cr, p); + cairo_paint(cr); + } + + (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0); +} + +JNIEXPORT jlong JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer +(JNIEnv *env, jobject obj, jint size) +{ + jint *dst; + jint *src = (jint *)getNativeObject(env, obj, BUFFER); + int i; + int t; + + g_assert( src != NULL ); + dst = g_malloc( size * sizeof( jint ) ); + + for(i = 0; i < size; i++ ) + { + t = (src[i] & 0x0000FF) << 16; + dst[i] = (src[i] & 0x00FF0000) >> 16; + dst[i] |= (src[i] & 0xFF00FF00); + dst[i] |= t; + } + + return PTR_TO_JLONG(dst); +} + +/** + * Create and return a cairo context for drawing to the surface. + */ +JNIEXPORT jlong JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_newCairoContext (JNIEnv *env, jobject obj) +{ + cairo_surface_t* surface = (cairo_surface_t *)getNativeObject(env, obj, SURFACE); + cairo_t *ptr; + g_assert(surface != NULL); + ptr = cairo_create(surface); + g_assert(ptr != NULL); + + return PTR_TO_JLONG(ptr); +} + +/** + * copyArea. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative (JNIEnv *env, + jobject obj, + jint x, jint y, + jint w, jint h, + jint dx, jint dy, + jint stride) +{ + int row; + int srcOffset, dstOffset; + jint *temp; + jint *pixeldata = (jint *)getNativeObject(env, obj, BUFFER); + g_assert( pixeldata != NULL ); + + temp = g_malloc( h * w * 4 ); + g_assert( temp != NULL ); + + srcOffset = x + (y * stride); + dstOffset = (x + dx) + ((y + dy) * stride); + + for( row = 0; row < h; row++ ) + memcpy( temp + (w * row), pixeldata + srcOffset + (stride * row), w * 4 ); + + for( row = 0; row < h; row++ ) + memcpy( pixeldata + dstOffset + (stride * row), temp + (w * row), w * 4 ); + + g_free( temp ); +} + +/* + * Sets the native object field. + */ +static void +setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer ) +{ + jclass cls; + jlong value; + jfieldID nofid; + cls = (*env)->GetObjectClass( env, obj ); + value = PTR_TO_JLONG(ptr); + nofid = (*env)->GetFieldID( env, cls, pointer, "J" ); + (*env)->SetLongField( env, obj, nofid, value ); + (*env)->DeleteLocalRef( env, cls ); +} + +/** + * Gets the native object field. + */ +static void * +getNativeObject( JNIEnv *env, jobject obj, const char *pointer ) +{ + jclass cls; + jlong value; + jfieldID nofid; + cls = (*env)->GetObjectClass( env, obj ); + nofid = (*env)->GetFieldID( env, cls, pointer, "J" ); + value = (*env)->GetLongField( env, obj, nofid ); + (*env)->DeleteLocalRef( env, cls ); + return JLONG_TO_PTR(void, value); +} diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c new file mode 100644 index 000000000..eea219569 --- /dev/null +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c @@ -0,0 +1,243 @@ +/* gnu_java_awt_peer_gtk_ComponentGraphics.c + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include "jcl.h" +#include "gtkpeer.h" +#include <cairo-xlib.h> +#include <gdk/gdktypes.h> +#include <gdk/gdkprivate.h> +#include <gdk/gdkx.h> +#include <X11/extensions/Xrender.h> + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gdk-pixbuf/gdk-pixdata.h> + +#include <cairo-ft.h> +#include <cairo-xlib.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "gnu_java_awt_peer_gtk_ComponentGraphics.h" + +static short flush_scheduled = 0; + +static gboolean flush (gpointer data __attribute__((unused))) +{ + gdk_threads_enter (); + + XFlush (GDK_DISPLAY ()); + flush_scheduled = 0; + + gdk_threads_leave (); + + return FALSE; +} + +/* The minimum time period between calls to XFlush, in + milliseconds. */ +#define MINIMUM_FLUSH_PERIOD 20 + +/* schedule_flush must be called with the GDK lock held. */ +static void +schedule_flush () +{ + if (!flush_scheduled) + { + g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL); + flush_scheduled = 1; + } +} + +void cp_gtk_grab_current_drawable(GtkWidget *widget, GdkDrawable **draw, + GdkWindow **win) +{ + g_assert (widget != NULL); + g_assert (draw != NULL); + g_assert (win != NULL); + + *win = widget->window; + + *draw = *win; + gdk_window_get_internal_paint_info (*win, draw, 0, 0); +} + +/** + * Returns whether the XRender extension is supported + */ +JNIEXPORT jboolean JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender + (JNIEnv *env __attribute__ ((unused)), jclass cls __attribute__ ((unused))) +{ +#if HAVE_XRENDER + int ev = 0, err = 0; + if( XRenderQueryExtension (GDK_DISPLAY (), &ev, &err) ) + return JNI_TRUE; +#endif + return JNI_FALSE; +} + + +JNIEXPORT jlong JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState + (JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer) +{ + Drawable draw; + Display * dpy; + Visual * vis; + GdkDrawable *drawable; + cairo_surface_t *surface; + GdkWindow *win; + GtkWidget *widget = NULL; + void *ptr = NULL; + int width, height; + cairo_t *cr; + + gdk_threads_enter(); + + ptr = NSA_GET_PTR (env, peer); + g_assert (ptr != NULL); + + widget = GTK_WIDGET (ptr); + g_assert (widget != NULL); + + cp_gtk_grab_current_drawable (widget, &drawable, &win); + g_assert (drawable != NULL); + + width = widget->allocation.width; + height = widget->allocation.height; + + g_assert (drawable != NULL); + + draw = gdk_x11_drawable_get_xid(drawable); + g_assert (draw != (XID) 0); + + dpy = gdk_x11_drawable_get_xdisplay(drawable); + g_assert (dpy != NULL); + + vis = gdk_x11_visual_get_xvisual(gdk_drawable_get_visual(drawable)); + g_assert (vis != NULL); + + surface = cairo_xlib_surface_create (dpy, draw, vis, width, height); + g_assert (surface != NULL); + + cr = cairo_create (surface); + g_assert(cr != NULL); + + gdk_threads_leave(); + + return PTR_TO_JLONG(cr); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing + (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused))) +{ + gdk_threads_enter(); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing + (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused))) +{ + schedule_flush (); + gdk_threads_leave(); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative + (JNIEnv *env, jobject obj __attribute__((unused)), jobject peer, + jint x, jint y, jint w, jint h, jint dx, jint dy) +{ + GdkPixbuf *pixbuf; + GdkDrawable *drawable; + GdkWindow *win; + GtkWidget *widget = NULL; + void *ptr = NULL; + + gdk_threads_enter(); + + ptr = NSA_GET_PTR (env, peer); + g_assert (ptr != NULL); + + widget = GTK_WIDGET (ptr); + g_assert (widget != NULL); + + cp_gtk_grab_current_drawable (widget, &drawable, &win); + g_assert (drawable != NULL); + + pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h ); + gdk_pixbuf_get_from_drawable( pixbuf, drawable, NULL, x, y, 0, 0, w, h ); + gdk_draw_pixbuf (drawable, NULL, pixbuf, + 0, 0, x + dx, y + dy, + w, h, + GDK_RGB_DITHER_NORMAL, 0, 0); + gdk_threads_leave(); +} + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphics_drawVolatile +(JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer, + jobject img, jint x, jint y, jint w, jint h) +{ + GdkPixmap *pixmap; + GtkWidget *widget = NULL; + void *ptr = NULL; + GdkGC *gc; + + gdk_threads_enter(); + + ptr = NSA_GET_PTR (env, peer); + g_assert (ptr != NULL); + + widget = GTK_WIDGET (ptr); + g_assert (widget != NULL); + + pixmap = cp_gtk_get_pixmap( env, img ); + + gc = gdk_gc_new(GDK_DRAWABLE(widget->window)); + gdk_draw_drawable(GDK_DRAWABLE(widget->window), + gc, + pixmap, + 0, 0, + x, y, + w, h); + + schedule_flush (); + + gdk_threads_leave(); +} diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c new file mode 100644 index 000000000..76caa5d0c --- /dev/null +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c @@ -0,0 +1,132 @@ +/* gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include "jcl.h" +#include "gtkpeer.h" +#include <cairo-xlib.h> +#include <gdk/gdktypes.h> +#include <gdk/gdkprivate.h> +#include <gdk/gdkx.h> + +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gdk-pixbuf/gdk-pixdata.h> + +#include <cairo-ft.h> +#include <cairo-xlib.h> + +#include <stdio.h> +#include <stdlib.h> + +#include "gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h" + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_getPixbuf + (JNIEnv *env, jobject obj __attribute__((unused)), + jobject peer, jobject image) +{ + gint width, height; + GdkPixbuf *pixbuf; + GdkDrawable *drawable; + GdkWindow *win; + GtkWidget *widget = NULL; + void *ptr = NULL; + + gdk_threads_enter(); + + ptr = NSA_GET_PTR (env, peer); + g_assert (ptr != NULL); + + widget = GTK_WIDGET (ptr); + g_assert (widget != NULL); + + cp_gtk_grab_current_drawable (widget, &drawable, &win); + g_assert (drawable != NULL); + + pixbuf = cp_gtk_image_get_pixbuf( env, image ); + g_assert( pixbuf != NULL); + + width = gdk_pixbuf_get_width( pixbuf ); + height = gdk_pixbuf_get_height( pixbuf ); + + gdk_pixbuf_get_from_drawable( pixbuf, /* destination pixbuf */ + drawable, + NULL, /* colormap */ + 0, 0, 0, 0, + width, height ); + gdk_threads_leave(); +} + + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_copyPixbuf + (JNIEnv *env, jobject obj __attribute__((unused)), + jobject peer, jobject image, + int x __attribute__((unused)), int y __attribute__((unused)), + int width __attribute__((unused)), int height __attribute__((unused))) +{ + gint pwidth, pheight; + GdkPixbuf *pixbuf; + GdkDrawable *drawable; + GdkWindow *win; + GtkWidget *widget = NULL; + void *ptr = NULL; + + gdk_threads_enter(); + + ptr = NSA_GET_PTR (env, peer); + g_assert (ptr != NULL); + + widget = GTK_WIDGET (ptr); + g_assert (widget != NULL); + + cp_gtk_grab_current_drawable (widget, &drawable, &win); + g_assert (drawable != NULL); + + pixbuf = cp_gtk_image_get_pixbuf( env, image ); + g_assert( pixbuf != NULL); + + pwidth = gdk_pixbuf_get_width( pixbuf ); + pheight = gdk_pixbuf_get_height( pixbuf ); + + gdk_draw_pixbuf (drawable, NULL, pixbuf, + 0, 0, 0, 0, + pwidth, pheight, + GDK_RGB_DITHER_NORMAL, 0, 0); + + gdk_threads_leave(); +} + diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c index 0726fb531..8b5609141 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c @@ -35,6 +35,13 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#include <pango/pango.h> +#include <pango/pangoft2.h> +#include <pango/pangofc-font.h> +#include <freetype/ftglyph.h> +#include <freetype/ftoutln.h> +#include <freetype/fttypes.h> +#include <freetype/tttables.h> #include "gdkfont.h" #include "gnu_java_awt_peer_gtk_GdkFontPeer.h" @@ -114,6 +121,25 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose } +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkFontPeer_releasePeerGraphicsResource + (JNIEnv *env, jobject java_font) +{ + struct peerfont *pfont = NULL; + + gdk_threads_enter(); + + pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font); + g_assert (pfont != NULL); + if (pfont->graphics_resource != NULL) + { + cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource); + pfont->graphics_resource = NULL; + } + + gdk_threads_leave(); +} + JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector (JNIEnv *env, jobject self, @@ -389,7 +415,7 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont - (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D) + (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size) { struct peerfont *pfont = NULL; char const *family_name = NULL; @@ -426,22 +452,11 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont if (style & java_awt_font_ITALIC) pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC); - if (useGraphics2D) - { - pango_font_description_set_size (pfont->desc, size * PANGO_SCALE); - if (pfont->ctx == NULL) - { - ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ()); - pfont->ctx = pango_ft2_font_map_create_context (ft2_map); - } - } - else + pango_font_description_set_size (pfont->desc, size * PANGO_SCALE); + if (pfont->ctx == NULL) { - /* GDK uses a slightly different DPI setting. */ - pango_font_description_set_size (pfont->desc, - size * cp_gtk_dpi_conversion_factor); - if (pfont->ctx == NULL) - pfont->ctx = gdk_pango_context_get(); + ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ()); + pfont->ctx = pango_ft2_font_map_create_context (ft2_map); } g_assert (pfont->ctx != NULL); @@ -465,3 +480,64 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont } +JNIEXPORT jbyteArray JNICALL +Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTrueTypeTable + (JNIEnv *env, jobject self, jbyte n, jbyte a, jbyte m, jbyte e) +{ + struct peerfont *pfont = NULL; + FT_Face face; + FT_ULong length = 0; + FT_ULong tag; + int error; + FT_Byte *buffer; + jbyteArray result_array; + jbyte *rbuf; + + pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self); + if(pfont == NULL) + return NULL; + + gdk_threads_enter (); + face = pango_fc_font_lock_face ((PangoFcFont *)pfont->font); + tag = FT_MAKE_TAG( n, a, m, e ); + + /* Get the length of the table requested */ + error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + if ( error ) + { + pango_fc_font_unlock_face ((PangoFcFont *)pfont->font); + gdk_threads_leave (); + return NULL; + } + + buffer = (FT_Byte *)g_malloc0( length ); + if ( buffer == NULL ) + { + pango_fc_font_unlock_face ((PangoFcFont *)pfont->font); + gdk_threads_leave (); + return NULL; + } + /* get the table data */ + error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + if ( error ) + { + pango_fc_font_unlock_face ((PangoFcFont *)pfont->font); + g_free(buffer); + gdk_threads_leave (); + return NULL; + } + + /* copy to a jbytearray */ + result_array = (*env)->NewByteArray (env, length); + + rbuf = (*env)->GetByteArrayElements (env, result_array, NULL); + memcpy(rbuf, buffer, length); + (*env)->ReleaseByteArrayElements (env, result_array, rbuf, 0); + + g_free(buffer); + pango_fc_font_unlock_face ((PangoFcFont *)pfont->font); + gdk_threads_leave (); + + /* done */ + return result_array; +} diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c deleted file mode 100644 index 29bc1855b..000000000 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c +++ /dev/null @@ -1,758 +0,0 @@ -/* gdkgraphics.c - Copyright (C) 1999 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -#include "gtkpeer.h" -#include "gdkfont.h" -#include "gnu_java_awt_peer_gtk_GdkGraphics.h" -#include <gdk/gdkprivate.h> -#include <gdk/gdkx.h> - -static jmethodID initComponentGraphicsUnlockedID; - -/* - * AWT applications may call Graphics methods from threads other than - * the GDK main thread, so we must call XFlush after each batch of - * drawing operations, otherwise animations flicker. Flushing after - * every graphics operation is excessive and negatively affects - * performance (PR 26486). We set the maximum frequency to 50 times - * per second, or a minimum period of 20 milliseconds between calls to - * XFlush. See gnu.classpath.examples.awt.AnimationApplet for an - * example applet that requires these XFlush calls. - */ - -static short flush_scheduled = 0; - -static gboolean flush (gpointer data __attribute__((unused))) -{ - gdk_threads_enter (); - - XFlush (GDK_DISPLAY ()); - flush_scheduled = 0; - - gdk_threads_leave (); - - return FALSE; -} - -/* The minimum time period between calls to XFlush, in - milliseconds. */ -#define MINIMUM_FLUSH_PERIOD 20 - -/* schedule_flush must be called with the GDK lock held. */ -static void -schedule_flush () -{ - if (!flush_scheduled) - { - g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL); - flush_scheduled = 1; - } -} - -void -cp_gtk_graphics_init_jni (void) -{ - jclass gdkgraphics; - - gdkgraphics = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(), - "gnu/java/awt/peer/gtk/GdkGraphics"); - - initComponentGraphicsUnlockedID = - (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics, - "initComponentGraphicsUnlocked", - "()V"); -} - -struct state_table *cp_gtk_native_graphics_state_table; - -static struct state_table *native_graphics_global_ref_table; - -#define NSA_GLOBAL_G_INIT(env, clazz) \ - native_graphics_global_ref_table = cp_gtk_init_state_table (env, clazz) - -#define NSA_GET_GLOBAL_G_REF(env, obj) \ - cp_gtk_get_state (env, obj, native_graphics_global_ref_table) - -#define NSA_SET_GLOBAL_G_REF(env, obj) \ - do {jobject *globRefPtr; \ - globRefPtr = (jobject *) malloc (sizeof (jobject)); \ - *globRefPtr = (*env)->NewGlobalRef (env, obj); \ - cp_gtk_set_state (env, obj, native_graphics_global_ref_table, (void *)globRefPtr);} while (0) - -#define NSA_DEL_GLOBAL_G_REF(env, obj) \ - do {jobject *globRefPtr = cp_gtk_get_state (env, obj, native_graphics_global_ref_table); \ - cp_gtk_remove_state_slot (env, obj, native_graphics_global_ref_table); \ - (*env)->DeleteGlobalRef (env, *globRefPtr); \ - free (globRefPtr);} while (0) - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_initStaticState - (JNIEnv *env, jclass clazz) -{ - gdk_threads_enter(); - - NSA_G_INIT (env, clazz); - NSA_GLOBAL_G_INIT (env, clazz); - - gdk_threads_leave(); -} - -#define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d)) - -static GdkPoint *translate_points (JNIEnv *env, jintArray xpoints, - jintArray ypoints, jint npoints, - jint x_offset, jint y_offset); -static void realize_cb (GtkWidget *widget, jobject jgraphics); - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeCopyState - (JNIEnv *env, jobject obj, jobject old) -{ - struct graphics *g = NULL; - struct graphics *g_old = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) g_malloc (sizeof (struct graphics)); - g_old = (struct graphics *) NSA_GET_G_PTR (env, old); - - *g = *g_old; - - g->gc = gdk_gc_new (g->drawable); - gdk_gc_copy (g->gc, g_old->gc); - - if (GDK_STABLE_IS_PIXMAP (g->drawable)) - g_object_ref (g->drawable); - else /* GDK_IS_WINDOW (g->drawable) */ - g_object_ref (g->drawable); - - if (g->cm != NULL) - g_object_ref (g->cm); - - NSA_SET_G_PTR (env, obj, g); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II - (JNIEnv *env, jobject obj, jint width, jint height) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) g_malloc (sizeof (struct graphics)); - g->x_offset = g->y_offset = 0; - - g->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height, - gdk_rgb_get_visual ()->depth); - g->cm = gdk_rgb_get_colormap (); - - if (g->cm != NULL) - g_object_ref (g->cm); - g->gc = gdk_gc_new (g->drawable); - - NSA_SET_G_PTR (env, obj, g); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage - (JNIEnv *env, jobject obj, jobject source) -{ - struct graphics *g = NULL; - GdkPixmap *pixmap = NULL; - - gdk_threads_enter (); - - pixmap = cp_gtk_image_get_pixmap (env, source); - g_assert(pixmap != NULL); - g_object_ref (pixmap); - - g = (struct graphics *) g_malloc (sizeof (struct graphics)); - g->x_offset = g->y_offset = 0; - - g->drawable = (GdkDrawable *)pixmap; - - g->cm = gdk_drawable_get_colormap (g->drawable); - - if (g->cm != NULL) - g_object_ref (g->cm); - g->gc = gdk_gc_new (g->drawable); - - NSA_SET_G_PTR (env, obj, g); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked - (JNIEnv *env, jobject obj, jobject peer) -{ - struct graphics *g = NULL; - void *ptr = NULL; - GtkWidget *widget = NULL; - GdkColor color; - - g = (struct graphics *) g_malloc (sizeof (struct graphics)); - ptr = NSA_GET_PTR (env, peer); - g->x_offset = 0; - g->y_offset = 0; - - widget = GTK_WIDGET (ptr); - g->drawable = (GdkDrawable *) widget->window; - - g_object_ref (g->drawable); - g->cm = gtk_widget_get_colormap (widget); - - if (g->cm != NULL) - g_object_ref (g->cm); - - g->gc = gdk_gc_new (g->drawable); - gdk_gc_copy (g->gc, widget->style->fg_gc[GTK_STATE_NORMAL]); - color = widget->style->fg[GTK_STATE_NORMAL]; - - NSA_SET_G_PTR (env, obj, g); -} - -/* copy the native state of the peer (GtkWidget *) to the native state - of the graphics object */ -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2 - (JNIEnv *env, jobject obj, jobject peer) -{ - gdk_threads_enter (); - Java_gnu_java_awt_peer_gtk_GdkGraphics_initStateUnlocked - (env, obj, peer); - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals - (JNIEnv *env, jobject obj, jobject peer) -{ - void *ptr = NULL; - jobject *gref = NULL; - - gdk_threads_enter (); - - NSA_SET_GLOBAL_G_REF (env, obj); - gref = NSA_GET_GLOBAL_G_REF (env, obj); - - ptr = NSA_GET_PTR (env, peer); - - g_signal_connect_after (G_OBJECT (ptr), "realize", - G_CALLBACK (realize_cb), *gref); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_nativeDispose - (JNIEnv *env, jobject obj) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_DEL_G_PTR (env, obj); - - /* check if dispose has been called already */ - if (!g) - { - gdk_threads_leave (); - return; - } - - XFlush (GDK_DISPLAY ()); - - if (g->gc != NULL) - g_object_unref (g->gc); - - if (GDK_STABLE_IS_PIXMAP (g->drawable)) - g_object_unref (g->drawable); - else if (g->drawable != NULL) - g_object_unref (g->drawable); - - if (g->cm != NULL) - g_object_unref (g->cm); - - g_free (g); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative - (JNIEnv *env, jobject obj, jint x, jint y) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - g->x_offset += x; - g->y_offset += y; - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString - (JNIEnv *env, jobject obj, jobject font, jstring str, jint x, jint y) -{ - struct peerfont *pfont = NULL; - struct graphics *g = NULL; - const char *cstr = NULL; - const char *sTmp = NULL; - char *tmp = NULL; - char *p = NULL; - int count = 0; - int charSize = 0; - int baseline_y = 0; - PangoLayoutIter *iter = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - g_assert (g != NULL); - - pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font); - g_assert (pfont != NULL); - - cstr = (*env)->GetStringUTFChars (env, str, NULL); - g_assert (cstr != NULL); - - charSize = sizeof(char); - p = malloc((strlen(cstr) + 1) * charSize); - g_assert (p != NULL); - - tmp = p; - sTmp = cstr; - for (; *sTmp != '\0'; sTmp++) - if (((unsigned char) *sTmp) >= ' ') - { - *p = *sTmp; - count++; - p++; - } - *p = '\0'; - - p = realloc(tmp, (count + 1) * charSize); - g_assert (p != NULL); - pango_layout_set_text (pfont->layout, p, -1); - free(p); - - pango_layout_set_font_description (pfont->layout, pfont->desc); - iter = pango_layout_get_iter (pfont->layout); - - baseline_y = pango_layout_iter_get_baseline (iter); - - gdk_draw_layout (g->drawable, g->gc, - x + g->x_offset, - y + g->y_offset - PANGO_PIXELS (baseline_y), - pfont->layout); - - pango_layout_iter_free (iter); - pango_layout_set_text (pfont->layout, "", -1); - - schedule_flush (); - - (*env)->ReleaseStringUTFChars (env, str, cstr); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine - (JNIEnv *env, jobject obj, jint x, jint y, jint x2, jint y2) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_line (g->drawable, g->gc, - x + g->x_offset, y + g->y_offset, - x2 + g->x_offset, y2 + g->y_offset); - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_rectangle (g->drawable, g->gc, TRUE, - x + g->x_offset, y + g->y_offset, width, height); - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_rectangle (g->drawable, g->gc, FALSE, - x + g->x_offset, y + g->y_offset, width, height); - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea - (JNIEnv *env, jobject obj, jint x, jint y, - jint width, jint height, jint dx, jint dy) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_drawable ((GdkWindow *)g->drawable, - g->gc, - (GdkWindow *)g->drawable, - x + g->x_offset, y + g->y_offset, - x + g->x_offset + dx, y + g->y_offset + dy, - width, height); - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height) -{ - struct graphics *g = NULL; - GdkGCValues saved; - GtkWidget *widget = NULL; - union widget_union w; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - if (!g) - { - gdk_threads_leave (); - return; - } - - if (GDK_IS_WINDOW (g->drawable)) - { - w.widget = &widget; - gdk_window_get_user_data (GDK_WINDOW (g->drawable), w.void_widget); - if (widget == NULL || !GTK_IS_EVENT_BOX (widget)) - gdk_window_clear_area ((GdkWindow *) g->drawable, - x + g->x_offset, y + g->y_offset, - width, height); - } - else - { - gdk_gc_get_values (g->gc, &saved); - gdk_gc_set_background (g->gc, &(saved.background)); - gdk_draw_rectangle (g->drawable, g->gc, TRUE, - x + g->x_offset, y + g->y_offset, width, height); - gdk_gc_set_foreground (g->gc, &(saved.foreground)); - } - - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction - (JNIEnv *env, jobject obj, jint func) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_gc_set_function (g->gc, func); - - gdk_threads_leave (); -} - - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor - (JNIEnv *env, jobject obj, jint red, jint green, jint blue) -{ - GdkColor color; - struct graphics *g = NULL; - - gdk_threads_enter (); - - color.red = red << 8; - color.green = green << 8; - color.blue = blue << 8; - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - if (g->cm != NULL) - gdk_colormap_alloc_color (g->cm, &color, TRUE, TRUE); - - gdk_gc_set_foreground (g->gc, &color); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height, - jint angle1, jint angle2) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_arc (g->drawable, g->gc, FALSE, - x + g->x_offset, y + g->y_offset, - width, height, angle1 << 6, angle2 << 6); - schedule_flush (); - - gdk_threads_leave (); -} - -static GdkPoint * -translate_points (JNIEnv *env, jintArray xpoints, jintArray ypoints, - jint npoints, jint x_offset, jint y_offset) -{ - GdkPoint *points; - jint *x, *y; - int i; - - /* allocate one more point than necessary, in case we need to tack - on an extra due to the semantics of Java polygons. */ - points = g_malloc (sizeof (GdkPoint) * (npoints + 1)); - - x = (*env)->GetIntArrayElements (env, xpoints, NULL); - y = (*env)->GetIntArrayElements (env, ypoints, NULL); - - for (i = 0; i < npoints; i++) - { - points[i].x = x[i] + x_offset; - points[i].y = y[i] + y_offset; - } - - (*env)->ReleaseIntArrayElements (env, xpoints, x, JNI_ABORT); - (*env)->ReleaseIntArrayElements (env, ypoints, y, JNI_ABORT); - - return points; -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline - (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints, - jint npoints) -{ - struct graphics *g = NULL; - GdkPoint *points = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - points = translate_points (env, xpoints, ypoints, npoints, - g->x_offset, g->y_offset); - - gdk_draw_lines (g->drawable, g->gc, points, npoints); - schedule_flush (); - - g_free (points); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon - (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints, - jint npoints) -{ - struct graphics *g = NULL; - GdkPoint *points = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - points = translate_points (env, xpoints, ypoints, npoints, - g->x_offset, g->y_offset); - - /* make sure the polygon is closed, per Java semantics. - if it's not, we close it. */ - if (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y) - points[npoints++] = points[0]; - - gdk_draw_lines (g->drawable, g->gc, points, npoints); - schedule_flush (); - - g_free (points); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon - (JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints, - jint npoints) -{ - struct graphics *g = NULL; - GdkPoint *points = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - points = translate_points (env, xpoints, ypoints, npoints, - g->x_offset, g->y_offset); - gdk_draw_polygon (g->drawable, g->gc, TRUE, points, npoints); - schedule_flush (); - - g_free (points); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height, - jint angle1, jint angle2) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_arc (g->drawable, g->gc, TRUE, - x + g->x_offset, y + g->y_offset, - width, height, angle1 << 6, angle2 << 6); - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_arc (g->drawable, g->gc, FALSE, - x + g->x_offset, y + g->y_offset, - width, height, 0, 23040); - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height) -{ - struct graphics *g = NULL; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - gdk_draw_arc (g->drawable, g->gc, TRUE, - x + g->x_offset, y + g->y_offset, - width, height, 0, 23040); - schedule_flush (); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle - (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height) -{ - struct graphics *g = NULL; - GdkRectangle rectangle; - - gdk_threads_enter (); - - g = (struct graphics *) NSA_GET_G_PTR (env, obj); - - rectangle.x = x + g->x_offset; - rectangle.y = y + g->y_offset; - rectangle.width = width; - rectangle.height = height; - - gdk_gc_set_clip_rectangle (g->gc, &rectangle); - - gdk_threads_leave (); -} - -static void -realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject jgraphics) -{ - (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), - jgraphics, - initComponentGraphicsUnlockedID); - - NSA_DEL_GLOBAL_G_REF (cp_gtk_gdk_env(), jgraphics); -} diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c deleted file mode 100644 index b42f649a1..000000000 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c +++ /dev/null @@ -1,2018 +0,0 @@ -/* gnu_java_awt_peer_gtk_GdkGraphics2d.c - Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. - - This file is part of GNU Classpath. - - GNU Classpath is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - GNU Classpath is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNU Classpath; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. - - Linking this library statically or dynamically with other modules is - making a combined work based on this library. Thus, the terms and - conditions of the GNU General Public License cover the whole - combination. - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent - modules, and to copy and distribute the resulting executable under - terms of your choice, provided that you also meet, for each linked - independent module, the terms and conditions of the license of that - module. An independent module is a module which is not derived from - or based on this library. If you modify this library, you may extend - this exception to your version of the library, but you are not - obligated to do so. If you do not wish to do so, delete this - exception statement from your version. */ - -#include "jcl.h" -#include "gtkcairopeer.h" -#include "gdkfont.h" -#include "gnu_java_awt_peer_gtk_GdkGraphics2D.h" -#include <gdk/gdktypes.h> -#include <gdk/gdkprivate.h> -#include <gdk/gdkx.h> -#include <X11/extensions/Xrender.h> - -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk-pixbuf/gdk-pixdata.h> - -#include <cairo-ft.h> -#include <cairo-xlib.h> - -#include <stdio.h> -#include <stdlib.h> - -static jmethodID initComponentGraphics2DUnlockedID; - -void -cp_gtk_graphics2d_init_jni (void) -{ - jclass gdkgraphics2d; - JNIEnv *env = cp_gtk_gdk_env(); - - gdkgraphics2d = (*env)->FindClass (env, - "gnu/java/awt/peer/gtk/GdkGraphics2D"); - if ((*env)->ExceptionOccurred(env)) - return; - - initComponentGraphics2DUnlockedID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics2d, - "initComponentGraphics2DUnlocked", - "()V"); -} - -static struct state_table *native_graphics2d_state_table; - -#define NSA_G2D_INIT(env, clazz) \ - native_graphics2d_state_table = cp_gtk_init_state_table (env, clazz) - -#define NSA_GET_G2D_PTR(env, obj) \ - cp_gtk_get_state (env, obj, native_graphics2d_state_table) - -#define NSA_SET_G2D_PTR(env, obj, ptr) \ - cp_gtk_set_state (env, obj, native_graphics2d_state_table, (void *)ptr) - -#define NSA_DEL_G2D_PTR(env, obj) \ - cp_gtk_remove_state_slot (env, obj, native_graphics2d_state_table) - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState - (JNIEnv *env, jclass clazz) -{ - gdk_threads_enter(); - - NSA_G2D_INIT (env, clazz); - - gdk_threads_leave(); -} - -/* these public final constants are part of the java2d public API, so we - write them explicitly here to save fetching them from the constant pool - all the time. */ - -#ifndef min -#define min(x,y) ((x) < (y) ? (x) : (y)) -#endif - -enum java_awt_alpha_composite_rule - { - java_awt_alpha_composite_CLEAR = 1, - java_awt_alpha_composite_SRC = 2, - java_awt_alpha_composite_SRC_OVER = 3, - java_awt_alpha_composite_DST_OVER = 4, - java_awt_alpha_composite_SRC_IN = 5, - java_awt_alpha_composite_DST_IN = 6, - java_awt_alpha_composite_SRC_OUT = 7, - java_awt_alpha_composite_DST_OUT = 8, - java_awt_alpha_composite_DST = 9, - java_awt_alpha_composite_SRC_ATOP = 10, - java_awt_alpha_composite_DST_ATOP = 11, - java_awt_alpha_composite_XOR = 12 - }; - -enum java_awt_basic_stroke_join_rule - { - java_awt_basic_stroke_JOIN_MITER = 0, - java_awt_basic_stroke_JOIN_ROUND = 1, - java_awt_basic_stroke_JOIN_BEVEL = 2 - }; - -enum java_awt_basic_stroke_cap_rule - { - java_awt_basic_stroke_CAP_BUTT = 0, - java_awt_basic_stroke_CAP_ROUND = 1, - java_awt_basic_stroke_CAP_SQUARE = 2 - }; - -enum java_awt_geom_path_iterator_winding_rule - { - java_awt_geom_path_iterator_WIND_EVEN_ODD = 0, - java_awt_geom_path_iterator_WIND_NON_ZERO = 1 - }; - -enum java_awt_rendering_hints_filter - { - java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0, - java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1, - java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2, - java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3, - java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4 - - }; - -static int -peer_is_disposed(JNIEnv *env, jobject obj) -{ - static jfieldID fid = NULL; - jclass cls; - jobject peer; - - return 0; - - if (fid == NULL) - { - cls = (*env)->GetObjectClass(env, obj); - fid = (*env)->GetFieldID(env, cls, "component", - "Lgnu/java/awt/peer/gtk/GtkComponentPeer;"); - } - g_assert(fid != NULL); - peer = (*env)->GetObjectField(env, obj, fid); - if (peer == NULL || NSA_GET_PTR (env, peer) != NULL) - return 0; - else - { - return 1; - } -} - - -static void -grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win) -{ - g_assert (widget != NULL); - g_assert (draw != NULL); - g_assert (win != NULL); - - *win = widget->window; - - *draw = *win; - gdk_window_get_internal_paint_info (*win, draw, 0, 0); - g_object_ref (*draw); -} - - -static int -x_server_has_render_extension (void) -{ - int ev = 0, err = 0; - return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err); -} - -static void -init_graphics2d_as_pixbuf (struct graphics2d *gr) -{ - gint width, height; - gint bits_per_sample = 8; - gint total_channels = 4; - gboolean has_alpha = TRUE; - - g_assert (gr != NULL); - g_assert (gr->drawable != NULL); - - if (gr->debug) printf ("initializing graphics2d as pixbuf\n"); - gdk_drawable_get_size (gr->drawable, &width, &height); - gr->drawbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - has_alpha, bits_per_sample, - width, height); - g_assert (gr->drawbuf != NULL); - g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample); - g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels); - - gr->surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (gr->drawbuf), - CAIRO_FORMAT_ARGB32, - gdk_pixbuf_get_width (gr->drawbuf), - gdk_pixbuf_get_height (gr->drawbuf), - gdk_pixbuf_get_rowstride (gr->drawbuf)); - g_assert (gr->surface != NULL); - gr->mode = MODE_DRAWABLE_NO_RENDER; - if (gr->cr != NULL) - cairo_destroy (gr->cr); - gr->cr = cairo_create (gr->surface); -} - -static void -init_graphics2d_as_renderable (struct graphics2d *gr) -{ - Drawable draw; - Display * dpy; - Visual * vis; - - g_assert (gr != NULL); - g_assert (gr->drawable != NULL); - - gr->drawbuf = NULL; - - if (gr->debug) printf ("initializing graphics2d as renderable\n"); - draw = gdk_x11_drawable_get_xid (gr->drawable); - - dpy = gdk_x11_drawable_get_xdisplay (gr->drawable); - g_assert (dpy != NULL); - - vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable)); - g_assert (vis != NULL); - - gr->surface = cairo_xlib_surface_create (dpy, draw, vis, gr->width, gr->height); - g_assert (gr->surface != NULL); - gr->mode = MODE_DRAWABLE_WITH_RENDER; - if (gr->cr != NULL) - cairo_destroy (gr->cr); - gr->cr = cairo_create (gr->surface); -} - -static void -begin_drawing_operation (JNIEnv *env, struct graphics2d * gr) -{ - cairo_status_t cst = cairo_status (gr->cr); - if (cst != CAIRO_STATUS_SUCCESS) - { - const char *detail = cairo_status_to_string (cst); - JCL_ThrowException (env, "java/lang/InternalError", detail); - (*env)->ExceptionDescribe (env); - return; - } - - switch (gr->mode) - { - case MODE_DRAWABLE_WITH_RENDER: - break; - - case MODE_DRAWABLE_NO_RENDER: - { - - gint drawable_width, drawable_height; - gint pixbuf_width, pixbuf_height; - gint width, height; - - gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height); - pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf); - pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf); - width = min (drawable_width, pixbuf_width); - height = min (drawable_height, pixbuf_height); - - gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */ - gr->drawable, - NULL, /* colormap */ - 0, 0, 0, 0, - width, height); - - if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n", - width, height); - } - break; - - case MODE_JAVA_ARRAY: - { - jboolean isCopy; - gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &isCopy); - gr->isCopy |= isCopy; - if (gr->isCopy) - { - /* Make sure that the pixel buffer copy is already initalized, - i.e. we already failed to get direct access in initState. */ - g_assert (gr->javabuf_copy != NULL); - memcpy (gr->javabuf_copy, gr->javabuf, gr->width * gr->height * 4); - } - } - break; - } -} - -static void -end_drawing_operation (JNIEnv *env, struct graphics2d * gr) -{ - cairo_status_t cst = cairo_status (gr->cr); - if (cst != CAIRO_STATUS_SUCCESS) - { - /* Report error. */ - const char *detail = cairo_status_to_string (cst); - JCL_ThrowException (env, "java/lang/InternalError", detail); - (*env)->ExceptionDescribe (env); - - /* Recreate cairo status. */ - cairo_destroy (gr->cr); - gr->cr = cairo_create (gr->surface); - return; - } - - switch (gr->mode) - { - case MODE_DRAWABLE_WITH_RENDER: - break; - - case MODE_DRAWABLE_NO_RENDER: - { - - gint drawable_width, drawable_height; - gint pixbuf_width, pixbuf_height; - gint width, height; - - gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height); - pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf); - pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf); - width = min (drawable_width, pixbuf_width); - height = min (drawable_height, pixbuf_height); - - gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf, - 0, 0, 0, 0, - width, height, - GDK_RGB_DITHER_NORMAL, 0, 0); - - if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n", - width, height); - } - break; - - case MODE_JAVA_ARRAY: - if (gr->isCopy) - memcpy (gr->javabuf, gr->javabuf_copy, gr->width * gr->height * 4); - (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT); - } -} - - -static void -update_pattern_transform (struct graphics2d *gr) -{ - cairo_matrix_t mat; - - g_assert (gr != NULL); - if (gr->pattern == NULL) - return; - - cairo_get_matrix (gr->cr, &mat); - cairo_pattern_set_matrix (gr->pattern, &mat); -} - -static void -check_for_debug (struct graphics2d *gr) -{ - gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL); -} - -static void -realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject peer) -{ - (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), - peer, - initComponentGraphics2DUnlockedID); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState - (JNIEnv *env, jobject obj, jobject old) -{ - struct graphics2d *g = NULL, *g_old = NULL; - - gdk_threads_enter(); - - g = (struct graphics2d *) g_malloc (sizeof (struct graphics2d)); - g_assert (g != NULL); - memset (g, 0, sizeof(struct graphics2d)); - - g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old); - g_assert (g_old != NULL); - - if (g_old->debug) printf ("copying state from existing graphics2d\n"); - - g->debug = g_old->debug; - g->mode = g_old->mode; - - g->width = g_old->width; - g->height = g_old->height; - - if (g_old->mode == MODE_JAVA_ARRAY) - { - jint size = g->width * g->height * 4; - - g->jarray = (*env)->NewGlobalRef (env, g_old->jarray); - g->javabuf = (*env)->GetIntArrayElements (env, g->jarray, &g->isCopy); - g->isCopy = JNI_TRUE; - g->javabuf_copy = (jint *) g_malloc (size); - memcpy (g->javabuf_copy, g->javabuf, size); - g->surface = cairo_image_surface_create_for_data ((unsigned char *) g->javabuf, - CAIRO_FORMAT_ARGB32, - g->width, - g->height, - g->width * 4); - g_assert (g->surface != NULL); - g->cr = cairo_create (g->surface); - g_assert (g->cr != NULL); - (*env)->ReleaseIntArrayElements (env, g->jarray, g->javabuf, JNI_ABORT); - } - else - { - g->drawable = g_old->drawable; - g_object_ref (g->drawable); - - if (x_server_has_render_extension ()) - init_graphics2d_as_renderable (g); - else - init_graphics2d_as_pixbuf (g); - } - - if (g->pattern) - cairo_pattern_set_filter (g->pattern, CAIRO_FILTER_FAST); - - NSA_SET_G2D_PTR (env, obj, g); - - gdk_threads_leave(); -} - - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III -(JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height) -{ - struct graphics2d *gr = NULL; - jint *cairobuf = NULL; - - gdk_threads_enter(); - - gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d)); - g_assert (gr != NULL); - memset (gr, 0, sizeof(struct graphics2d)); - - check_for_debug (gr); - - if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n", - width, height); - - gr->width = width; - gr->height = height; - gr->jarray = (*env)->NewGlobalRef(env, jarr); - gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &gr->isCopy); - if (gr->isCopy) - { - /* We didn't get direct access to the pixel buffer, so we'll have to - maintain a separate copy for Cairo. */ - jint size = gr->width * gr->height * 4; - gr->javabuf_copy = (jint *) g_malloc (size); - memcpy (gr->javabuf_copy, gr->javabuf, size); - cairobuf = gr->javabuf_copy; - } - else - { - /* Have Cairo write directly to the Java array. */ - cairobuf = gr->javabuf; - } - gr->surface = cairo_image_surface_create_for_data ((unsigned char *) cairobuf, - CAIRO_FORMAT_ARGB32, - gr->width, - gr->height, - gr->width * 4); - g_assert (gr->surface != NULL); - gr->cr = cairo_create (gr->surface); - g_assert (gr->cr != NULL); - (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT); - - gr->mode = MODE_JAVA_ARRAY; - - if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n", - width, height); - - NSA_SET_G2D_PTR (env, obj, gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II - (JNIEnv *env, jobject obj, jint width, jint height) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d)); - g_assert (gr != NULL); - memset (gr, 0, sizeof(struct graphics2d)); - - check_for_debug (gr); - - if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n", - width, height); - - gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height, - gdk_rgb_get_visual ()->depth); - g_assert (gr->drawable != NULL); - - gr->width = width; - gr->height = height; - - if (x_server_has_render_extension ()) - init_graphics2d_as_renderable (gr); - else - init_graphics2d_as_pixbuf (gr); - - if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n", - width, height); - NSA_SET_G2D_PTR (env, obj, gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable - (JNIEnv *env, jobject self, jobject other, jint x, jint y) -{ - struct graphics2d *src = NULL; - struct graphics2d *dst = NULL; - gint s_height; - gint s_width; - gint d_height; - gint d_width; - gint height; - gint width; - cairo_matrix_t matrix; - cairo_operator_t tmp_op; - - gdk_threads_enter(); - - if (peer_is_disposed(env, self)) - { - gdk_threads_leave(); - return; - } - - src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other); - dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, self); - g_assert (src != NULL); - g_assert (dst != NULL); - - if (src->debug) printf ("copying from offscreen drawable\n"); - - begin_drawing_operation(env, dst); - - /* gdk_flush(); */ - - if (!GDK_IS_DRAWABLE (src->drawable) || - !GDK_IS_DRAWABLE (dst->drawable)) - { - gdk_threads_leave (); - return; - } - - gdk_drawable_get_size (src->drawable, &s_width, &s_height); - gdk_drawable_get_size (dst->drawable, &d_width, &d_height); - width = min (s_width, d_width); - height = min (s_height, d_height); - - cairo_get_matrix (src->cr, &matrix); - cairo_matrix_translate (&matrix, (double)-x, (double)-y); - if (src->pattern) - cairo_pattern_set_matrix (src->pattern, &matrix); - tmp_op = cairo_get_operator (dst->cr); - cairo_set_operator(dst->cr, CAIRO_OPERATOR_SOURCE); - cairo_set_source_surface (dst->cr, src->surface, 0, 0); - cairo_paint (dst->cr); - cairo_set_operator(dst->cr, tmp_op); - - cairo_matrix_translate (&matrix, (double)x, (double)y); - if (src->pattern) - cairo_pattern_set_matrix (src->pattern, &matrix); - - gdk_flush(); - - end_drawing_operation(env, dst); - - if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStateUnlocked - (JNIEnv *env, jobject obj, jobject peer) -{ - struct graphics2d *gr = NULL; - GtkWidget *widget = NULL; - void *ptr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - ptr = NSA_GET_PTR (env, peer); - g_assert (ptr != NULL); - - gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d)); - g_assert (gr != NULL); - memset (gr, 0, sizeof(struct graphics2d)); - - check_for_debug (gr); - - widget = GTK_WIDGET (ptr); - g_assert (widget != NULL); - - grab_current_drawable (widget, &(gr->drawable), &(gr->win)); - g_assert (gr->drawable != NULL); - - gr->width = widget->allocation.width; - gr->height = widget->allocation.height; - - if (x_server_has_render_extension ()) - init_graphics2d_as_renderable (gr); - else - init_graphics2d_as_pixbuf (gr); - - NSA_SET_G2D_PTR (env, obj, gr); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2 - (JNIEnv *env, jobject obj, jobject peer) -{ - struct graphics2d *gr = NULL; - GtkWidget *widget = NULL; - void *ptr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave (); - return; - } - - ptr = NSA_GET_PTR (env, peer); - g_assert (ptr != NULL); - - gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d)); - g_assert (gr != NULL); - memset (gr, 0, sizeof(struct graphics2d)); - - check_for_debug (gr); - - widget = GTK_WIDGET (ptr); - g_assert (widget != NULL); - - grab_current_drawable (widget, &(gr->drawable), &(gr->win)); - g_assert (gr->drawable != NULL); - - gr->width = widget->allocation.width; - gr->height = widget->allocation.height; - - if (x_server_has_render_extension ()) - init_graphics2d_as_renderable (gr); - else - init_graphics2d_as_pixbuf (gr); - - NSA_SET_G2D_PTR (env, obj, gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_connectSignals - (JNIEnv *env, jobject obj, jobject peer) -{ - void *ptr; - - gdk_threads_enter (); - - ptr = NSA_GET_PTR (env, peer); - - g_signal_connect_after (G_OBJECT (ptr), "realize", - G_CALLBACK (realize_cb), obj); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj); - - if (gr == NULL) - { - gdk_threads_leave(); - return; /* dispose has been called more than once */ - } - - if (gr->surface) - cairo_surface_destroy (gr->surface); - - cairo_destroy (gr->cr); - - if (gr->drawbuf) - g_object_unref (gr->drawbuf); - - if (gr->drawable) - g_object_unref (gr->drawable); - - if (gr->pattern) - cairo_pattern_destroy (gr->pattern); - - if (gr->pattern_surface) - cairo_surface_destroy (gr->pattern_surface); - - if (gr->pattern_pixels) - g_free (gr->pattern_pixels); - - if (gr->mode == MODE_JAVA_ARRAY) - { - (*env)->DeleteGlobalRef (env, gr->jarray); - if (gr->javabuf_copy) - g_free (gr->javabuf_copy); - } - - if (gr->debug) printf ("disposed of graphics2d\n"); - - g_free (gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient - (JNIEnv *env, jobject obj, - jdouble x1, jdouble y1, - jdouble x2, jdouble y2, - jint r1, jint g1, jint b1, jint a1, - jint r2, jint g2, jint b2, jint a2, - jboolean cyclic) -{ - gdk_threads_enter(); - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradientUnlocked - (env, obj, - x1, y1, x2, y2, - r1, g1, b1, a1, - r2, g2, b2, a2, - cyclic); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradientUnlocked - (JNIEnv *env, jobject obj, - jdouble x1, jdouble y1, - jdouble x2, jdouble y2, - jint r1, jint g1, jint b1, jint a1, - jint r2, jint g2, jint b2, jint a2, - jboolean cyclic) -{ - struct graphics2d *gr = NULL; - cairo_surface_t *surf = NULL; - cairo_t *cr2 = NULL; - cairo_matrix_t mat; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - - if (peer_is_disposed(env, obj)) - return; - - if (gr->debug) - printf ("setGradientUnlocked (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n", - x1, y1, - x2, y2, - r1, g1, b1, a1, - r2, g2, b2, a2); - - if (cyclic) - surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2); - else - surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2); - g_assert (surf != NULL); - - cr2 = cairo_create (surf); - - cairo_identity_matrix (cr2); - - cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0); - cairo_rectangle (cr2, 0, 0, 1, 2); - cairo_fill (cr2); - - cairo_set_source_rgba (cr2, r2 / 255.0, g2 / 255.0, b2 / 255.0, a2 / 255.0); - cairo_rectangle (cr2, 1, 0, 1, 2); - cairo_fill (cr2); - - if (cyclic) - { - cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0); - cairo_rectangle (cr2, 2, 0, 1, 2); - cairo_fill (cr2); - } - - cairo_matrix_init_identity (&mat); - - /* - consider the vector [x2 - x1, y2 - y1] = [p,q] - - this is a line in space starting at an 'origin' x1, y1. - - it can also be thought of as a "transformed" unit vector in either the - x or y directions. we have just *drawn* our gradient as a unit vector - (well, a 2-3x unit vector) in the x dimension. so what we want to know - is which transformation turns our existing unit vector into [p,q]. - - which means solving for M in - - [p,q] = M[1,0] - - [p,q] = |a b| [1,0] - |c d| - - [p,q] = [a,c], with b = d = 0. - - what does this mean? it means that our gradient is 1-dimensional; as - you move through the x axis of our 2 or 3 pixel gradient from logical - x positions 0 to 1, the transformation of your x coordinate under the - matrix M causes you to accumulate both x and y values in fill - space. the y value of a gradient coordinate is ignored, since the - gradient is one dimensional. which is correct. - - unfortunately we want the opposite transformation, it seems, because of - the way cairo is going to use this transformation. I'm a bit confused by - that, but it seems to work right, so we take reciprocals of values and - negate offsets. oh well. - - */ - { - double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1)); - double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1)); - double dx = (x1 == 0.) ? 0. : 1. / x1; - double dy = (y1 == 0.) ? 0. : 1. / y1; - cairo_pattern_t *p; - - cairo_matrix_init (&mat, - a, 0., - c, 0., - dx, dy); - - p = cairo_pattern_create_for_surface (surf); - cairo_pattern_set_matrix (p, &mat); - cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR); - } - - /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */ - /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */ - - if (gr->pattern) - cairo_pattern_destroy (gr->pattern); - - if (gr->pattern_surface) - cairo_surface_destroy (gr->pattern_surface); - - if (gr->pattern_pixels) - g_free (gr->pattern_pixels); - - gr->pattern_pixels = NULL; - gr->pattern_surface = surf; - gr->pattern = cairo_pattern_create_for_surface(surf); - - cairo_set_source (gr->cr, gr->pattern); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels - (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixelsUnlocked - (env, obj, jarr, w, h, stride); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixelsUnlocked - (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride) -{ - struct graphics2d *gr = NULL; - jint *jpixels = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - - if (gr->debug) - printf ("setTexturePixelsUnlocked (%d pixels, %dx%d, stride: %d)\n", - (*env)->GetArrayLength (env, jarr), w, h, stride); - - if (gr->pattern) - cairo_pattern_destroy (gr->pattern); - - if (gr->pattern_surface) - cairo_surface_destroy (gr->pattern_surface); - - if (gr->pattern_pixels) - g_free (gr->pattern_pixels); - - gr->pattern = NULL; - gr->pattern_surface = NULL; - gr->pattern_pixels = NULL; - - gr->pattern_pixels = (char *) g_malloc (h * stride * 4); - g_assert (gr->pattern_pixels != NULL); - - jpixels = (*env)->GetIntArrayElements (env, jarr, NULL); - g_assert (jpixels != NULL); - memcpy (gr->pattern_pixels, jpixels, h * stride * 4); - (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0); - - gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels, - CAIRO_FORMAT_ARGB32, - w, h, stride * 4); - g_assert (gr->pattern_surface != NULL); - gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface); - g_assert (gr->pattern != NULL); - cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT); - cairo_set_source (gr->cr, gr->pattern); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels - (JNIEnv *env, jobject obj, jintArray java_pixels, - jint w, jint h, jint stride, jdoubleArray java_matrix) -{ - struct graphics2d *gr = NULL; - jint *native_pixels = NULL; - jdouble *native_matrix = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - - if (gr->debug) - printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n", - (*env)->GetArrayLength (env, java_pixels), w, h, stride); - - native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL); - native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL); - g_assert (native_pixels != NULL); - g_assert (native_matrix != NULL); - g_assert ((*env)->GetArrayLength (env, java_matrix) == 6); - - begin_drawing_operation (env, gr); - - { - cairo_matrix_t mat; - cairo_pattern_t *p; - cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels, - CAIRO_FORMAT_ARGB32, - w, h, stride * 4); - cairo_matrix_init_identity (&mat); - cairo_matrix_init (&mat, - native_matrix[0], native_matrix[1], - native_matrix[2], native_matrix[3], - native_matrix[4], native_matrix[5]); - - p = cairo_pattern_create_for_surface (surf); - cairo_pattern_set_matrix (p, &mat); - if (gr->pattern) - cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern)); - cairo_set_source (gr->cr, p); - cairo_paint (gr->cr); - cairo_pattern_destroy (p); - cairo_surface_destroy (surf); - } - - end_drawing_operation (env, gr); - - (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0); - (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0); - - gdk_threads_leave(); -} - -/* passthrough methods to cairo */ - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_save\n"); - cairo_save (gr->cr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_restore\n"); - cairo_restore (gr->cr); - update_pattern_transform (gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix - (JNIEnv *env, jobject obj, jdoubleArray java_matrix) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrixUnlocked - (env, obj, java_matrix); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrixUnlocked - (JNIEnv *env, jobject obj, jdoubleArray java_matrix) -{ - struct graphics2d *gr = NULL; - jdouble *native_matrix = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - - /* cairoSetMatrix was called before this graphics object's component - was realized. */ - if (gr == NULL) - return; - - native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL); - g_assert (native_matrix != NULL); - g_assert ((*env)->GetArrayLength (env, java_matrix) == 6); - - if (gr->debug) - printf ("cairo_matrix_init [ %f, %f, %f, %f, %f, %f ]\n", - native_matrix[0], native_matrix[1], - native_matrix[2], native_matrix[3], - native_matrix[4], native_matrix[5]); - - { - cairo_matrix_t mat; - - cairo_matrix_init_identity (&mat); - cairo_matrix_init (&mat, - native_matrix[0], native_matrix[1], - native_matrix[2], native_matrix[3], - native_matrix[4], native_matrix[5]); - cairo_set_matrix (gr->cr, &mat); - } - - (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0); - update_pattern_transform (gr); -} - -static void -install_font_peer(cairo_t *cr, - struct peerfont *pfont, - int debug) -{ - cairo_font_face_t *ft; - FT_Face face = NULL; - - g_assert(cr != NULL); - g_assert(pfont != NULL); - - if (pfont->graphics_resource == NULL) - { - face = pango_ft2_font_get_face (pfont->font); - g_assert (face != NULL); - - ft = cairo_ft_font_face_create_for_ft_face (face, 0); - g_assert (ft != NULL); - - if (debug) printf ("install_font_peer made new cairo font for '%s' at %f\n", - face->family_name, - (pango_font_description_get_size (pfont->desc) / - (double)PANGO_SCALE)); - - cairo_set_font_face (cr, ft); - cairo_font_face_destroy (ft); - cairo_set_font_size (cr, - (pango_font_description_get_size (pfont->desc) / - (double)PANGO_SCALE)); - ft = cairo_get_font_face (cr); - pfont->graphics_resource = ft; - } - else - { - if (debug) printf ("install_font_peer reused existing font resource\n"); - ft = (cairo_font_face_t *) pfont->graphics_resource; - cairo_set_font_face (cr, ft); - } -} - - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource - (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font) -{ - struct peerfont *pfont = NULL; - - gdk_threads_enter(); - - g_assert(java_font != NULL); - - pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font); - g_assert (pfont != NULL); - if (pfont->graphics_resource != NULL) - { - cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource); - pfont->graphics_resource = NULL; - } - - gdk_threads_leave(); -} - -static void -paint_glyph_run(JNIEnv *env, - struct graphics2d *gr, - cairo_glyph_t **glyphs, - gint *n_glyphs, - PangoLayoutRun *run) -{ - gint i = 0; - gint x = 0, y = 0; - - g_assert (gr != NULL); - g_assert (glyphs != NULL); - g_assert (n_glyphs != NULL); - g_assert (run != NULL); - - if (run->glyphs != NULL && run->glyphs->num_glyphs > 0) - { - if (*n_glyphs < run->glyphs->num_glyphs) - { - *glyphs = g_realloc(*glyphs, - (sizeof(cairo_glyph_t) - * run->glyphs->num_glyphs)); - *n_glyphs = run->glyphs->num_glyphs; - } - - g_assert (*glyphs != NULL); - - if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs); - - for (i = 0; i < run->glyphs->num_glyphs; ++i) - { - (*glyphs)[i].index = run->glyphs->glyphs[i].glyph; - - (*glyphs)[i].x = - ((double) (x + run->glyphs->glyphs[i].geometry.x_offset)) - / ((double) PANGO_SCALE); - - (*glyphs)[i].y = - ((double) (y + run->glyphs->glyphs[i].geometry.y_offset)) - / ((double) PANGO_SCALE); - - if (gr->debug) printf(" (%ld @ %f,%f)", - (*glyphs)[i].index, - (*glyphs)[i].x, - (*glyphs)[i].y); - - x += run->glyphs->glyphs[i].geometry.width; - } - - if (gr->debug) printf("\n"); - begin_drawing_operation (env, gr); - cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs); - end_drawing_operation (env, gr); - } -} - - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGlyphVector - (JNIEnv *env, jobject self, - jobject font, - jfloat x, jfloat y, jint n, - jintArray java_codes, - jfloatArray java_positions) -{ - - struct graphics2d *gr = NULL; - struct peerfont *pfont = NULL; - cairo_glyph_t *glyphs = NULL; - int *native_codes; - float *native_positions; - jint i = 0; - - gdk_threads_enter (); - - g_assert (self != NULL); - g_assert (java_codes != NULL); - g_assert (java_positions != NULL); - - if (peer_is_disposed(env, self)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self); - g_assert (gr != NULL); - - pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font); - g_assert (pfont != NULL); - - install_font_peer(gr->cr, pfont, gr->debug); - - glyphs = g_malloc( sizeof(cairo_glyph_t) * n); - g_assert (glyphs != NULL); - - native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL); - native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL); - - for (i = 0; i < n; ++i) - { - glyphs[i].index = native_codes[i]; - glyphs[i].x = x + native_positions[ 2*i ]; - glyphs[i].y = y + native_positions[ 2*i + 1]; - } - - (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0); - (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0); - - begin_drawing_operation (env, gr); - cairo_show_glyphs (gr->cr, glyphs, n); - end_drawing_operation (env, gr); - - g_free(glyphs); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout - (JNIEnv *env, jobject self, jobject java_layout, jfloat x, jfloat y) -{ - /* - * FIXME: Some day we expect either cairo or pango will know how to make - * a pango layout paint to a cairo surface. that day is not yet here. - */ - - struct graphics2d *gr = NULL; - struct textlayout *tl = NULL; - PangoLayoutIter *i = NULL; - PangoLayoutRun *run = NULL; - cairo_glyph_t *glyphs = NULL; - gint n_glyphs = 0; - - gdk_threads_enter (); - - g_assert (self != NULL); - g_assert (java_layout != NULL); - - gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, self); - tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout); - - g_assert (gr != NULL); - g_assert (tl != NULL); - g_assert (tl->pango_layout != NULL); - - if (gr->debug) printf ("painting pango layout\n"); - - if (peer_is_disposed(env, self)) - { - gdk_threads_leave(); - return; - } - - i = pango_layout_get_iter (tl->pango_layout); - g_assert (i != NULL); - - cairo_translate (gr->cr, x, y); - - do - { - run = pango_layout_iter_get_run (i); - if (run != NULL) - paint_glyph_run (env, gr, &glyphs, &n_glyphs, run); - } - while (pango_layout_iter_next_run (i)); - - if (glyphs != NULL) - g_free (glyphs); - - cairo_translate (gr->cr, -x, -y); - - pango_layout_iter_free (i); - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator - (JNIEnv *env, jobject obj, jint op) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_set_operator %d\n", op); - switch ((enum java_awt_alpha_composite_rule) op) - { - case java_awt_alpha_composite_CLEAR: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR); - break; - - case java_awt_alpha_composite_SRC: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE); - break; - - case java_awt_alpha_composite_SRC_OVER: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER); - break; - - case java_awt_alpha_composite_DST_OVER: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER); - break; - - case java_awt_alpha_composite_SRC_IN: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN); - break; - - case java_awt_alpha_composite_DST_IN: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN); - break; - - case java_awt_alpha_composite_SRC_OUT: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT); - break; - - case java_awt_alpha_composite_DST_OUT: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT); - break; - - case java_awt_alpha_composite_DST: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST); - break; - - case java_awt_alpha_composite_SRC_ATOP: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP); - break; - - case java_awt_alpha_composite_DST_ATOP: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP); - break; - - case java_awt_alpha_composite_XOR: - cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR); - break; - } - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColor - (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColorUnlocked - (env, obj, r, g, b, a); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColorUnlocked - (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a) -{ - struct graphics2d *gr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - - /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider - colors in opposite pixel order. I have no idea why. thus when you - draw to a PixBuf, you must exchange the R and B components of your - color. */ - - if (gr->debug) - printf ("cairo_set_source_rgba (%f, %f, %f, %f)\n", r, g, b, a); - - if (gr->drawbuf) - cairo_set_source_rgba (gr->cr, b, g, r, a); - else - cairo_set_source_rgba (gr->cr, r, g, b, a); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule - (JNIEnv *env, jobject obj, jint rule) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule); - g_assert (gr != NULL); - switch ((enum java_awt_geom_path_iterator_winding_rule) rule) - { - case java_awt_geom_path_iterator_WIND_NON_ZERO: - cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING); - break; - case java_awt_geom_path_iterator_WIND_EVEN_ODD: - cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD); - break; - } - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth - (JNIEnv *env, jobject obj, jdouble width) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidthUnlocked - (env, obj, width); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidthUnlocked - (JNIEnv *env, jobject obj, jdouble width) -{ - struct graphics2d *gr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_set_line_width %f\n", width); - cairo_set_line_width (gr->cr, width); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap - (JNIEnv *env, jobject obj, jint cap) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCapUnlocked - (env, obj, cap); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCapUnlocked - (JNIEnv *env, jobject obj, jint cap) -{ - struct graphics2d *gr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_set_line_cap %d\n", cap); - switch ((enum java_awt_basic_stroke_cap_rule) cap) - { - case java_awt_basic_stroke_CAP_BUTT: - cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT); - break; - - case java_awt_basic_stroke_CAP_ROUND: - cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND); - break; - - case java_awt_basic_stroke_CAP_SQUARE: - cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE); - break; - } -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin - (JNIEnv *env, jobject obj, jint join) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoinUnlocked - (env, obj, join); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoinUnlocked - (JNIEnv *env, jobject obj, jint join) -{ - struct graphics2d *gr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_set_line_join %d\n", join); - switch ((enum java_awt_basic_stroke_join_rule) join) - { - case java_awt_basic_stroke_JOIN_MITER: - cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER); - break; - - case java_awt_basic_stroke_JOIN_ROUND: - cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND); - break; - - case java_awt_basic_stroke_JOIN_BEVEL: - cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL); - break; - } -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash - (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDashUnlocked - (env, obj, dashes, ndash, offset); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDashUnlocked - (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset) -{ - struct graphics2d *gr = NULL; - jdouble *dasharr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_set_dash\n"); - dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL); - g_assert (dasharr != NULL); - cairo_set_dash (gr->cr, dasharr, ndash, offset); - (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit - (JNIEnv *env, jobject obj, jdouble miter) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimitUnlocked - (env, obj, miter); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimitUnlocked - (JNIEnv *env, jobject obj, jdouble miter) -{ - struct graphics2d *gr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter); - cairo_set_miter_limit (gr->cr, miter); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - - if (gr == NULL) - { - gdk_threads_leave (); - return; - } - - if (gr->debug) printf ("cairo_new_path\n"); - cairo_new_path (gr->cr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo - (JNIEnv *env, jobject obj, jdouble x, jdouble y) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y); - cairo_move_to (gr->cr, x, y); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo - (JNIEnv *env, jobject obj, jdouble x, jdouble y) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y); - cairo_line_to (gr->cr, x, y); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo - (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) - printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n", - x1, y1, x2, y2, x3, y3); - cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo - (JNIEnv *env, jobject obj, jdouble dx, jdouble dy) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy); - cairo_rel_move_to (gr->cr, dx, dy); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo - (JNIEnv *env, jobject obj, jdouble dx, jdouble dy) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy); - cairo_rel_line_to (gr->cr, dx, dy); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo - (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) - printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n", - dx1, dy1, dx2, dy2, dx3, dy3); - cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle - (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - - if (gr == NULL) - { - gdk_threads_leave (); - return; - } - - if (gr->debug) - printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height); - cairo_rectangle (gr->cr, x, y, width, height); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_close_path\n"); - cairo_close_path (gr->cr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_stroke\n"); - begin_drawing_operation (env, gr); - cairo_stroke (gr->cr); - end_drawing_operation (env, gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - if (gr->debug) printf ("cairo_fill\n"); - begin_drawing_operation (env, gr); - cairo_fill (gr->cr); - end_drawing_operation (env, gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip - (JNIEnv *env, jobject obj) -{ - struct graphics2d *gr = NULL; - - gdk_threads_enter(); - - if (peer_is_disposed(env, obj)) - { - gdk_threads_leave(); - return; - } - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - - if (gr == NULL) - { - gdk_threads_leave (); - return; - } - - if (gr->debug) printf ("cairo_clip\n"); - begin_drawing_operation (env, gr); - cairo_reset_clip (gr->cr); - cairo_clip (gr->cr); - end_drawing_operation (env, gr); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter - (JNIEnv *env, jobject obj, jint filter) -{ - gdk_threads_enter(); - - Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilterUnlocked - (env, obj, filter); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilterUnlocked - (JNIEnv *env, jobject obj, jint filter) -{ - struct graphics2d *gr = NULL; - - if (peer_is_disposed(env, obj)) - return; - - gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); - g_assert (gr != NULL); - - if (gr->pattern == NULL) - return; - - if (gr->debug) printf ("cairo_pattern_set_filter %d\n", filter); - switch ((enum java_awt_rendering_hints_filter) filter) - { - case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR: - cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST); - break; - case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR: - cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR); - break; - case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED: - cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST); - break; - case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT: - cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST); - break; - case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY: - cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST); - break; - } -} diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c index edce3917d..92f2d37ca 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c @@ -1,5 +1,5 @@ /* gnu_java_awt_GdkTextLayout.c - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -47,6 +47,7 @@ #include "native_state.h" #include "gdkfont.h" #include "gnu_java_awt_peer_gtk_GdkTextLayout.h" +#include "cairographics2d.h" struct state_table *cp_gtk_native_text_layout_state_table; @@ -60,6 +61,9 @@ typedef struct gp double sy; } generalpath ; +static void paint_glyph_run(cairo_t *cr, cairo_glyph_t **glyphs, + gint *n_glyphs, PangoLayoutRun *run); + JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState (JNIEnv *env, jclass clazz) @@ -93,8 +97,6 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText gchar *str = NULL; gint len = 0; - gdk_threads_enter (); - g_assert(self != NULL); g_assert(text != NULL); @@ -106,13 +108,37 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText str = (gchar *)(*env)->GetStringUTFChars (env, text, NULL); g_assert (str != NULL); - pango_layout_set_text (tl->pango_layout, text, len); + gdk_threads_enter (); + + pango_layout_set_text (tl->pango_layout, str, len); (*env)->ReleaseStringUTFChars (env, text, str); gdk_threads_leave (); } +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkTextLayout_setFont (JNIEnv *env, jobject obj, jobject font) +{ + struct textlayout *tl; + struct peerfont *pf; + + g_assert(obj != NULL); + g_assert(font != NULL); + + tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, obj); + g_assert(tl != NULL); + g_assert(tl->pango_layout != NULL); + pf = (struct peerfont *)NSA_GET_FONT_PTR (env, font); + g_assert(pf != NULL); + + gdk_threads_enter (); + + pango_layout_set_font_description(tl->pango_layout, pf->desc); + + gdk_threads_leave (); +} + JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos (JNIEnv *env, jobject self, jint idx, jdoubleArray javaPos) @@ -207,10 +233,108 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose gdk_threads_leave (); } +/** + * Draw this textlayout on a cairo surface + * FIXME: Seems completely broken. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GdkTextLayout_cairoDrawGdkTextLayout + (JNIEnv *env, jobject obj, jobject cairographics, jfloat x, jfloat y) +{ + /* + * FIXME: Some day we expect either cairo or pango will know how to make + * a pango layout paint to a cairo surface. that day is not yet here. + */ + + cairo_t *cr; + struct textlayout *tl = NULL; + PangoLayoutIter *i = NULL; + PangoLayoutRun *run = NULL; + cairo_glyph_t *glyphs = NULL; + gint n_glyphs = 0; + + g_assert (cairographics != NULL); + + cr = cp_gtk_get_cairo_t(env, cairographics); + tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, obj); + + g_assert (cr != NULL); + g_assert (tl != NULL); + g_assert (tl->pango_layout != NULL); + + gdk_threads_enter (); + + i = pango_layout_get_iter (tl->pango_layout); + g_assert (i != NULL); + + cairo_translate (cr, x, y); + + do + { + run = pango_layout_iter_get_run (i); + if (run != NULL) + paint_glyph_run (cr, &glyphs, &n_glyphs, run); + } + while (pango_layout_iter_next_run (i)); + + if (glyphs != NULL) + g_free (glyphs); + + cairo_translate (cr, -x, -y); + + pango_layout_iter_free (i); + + gdk_threads_leave (); +} + +static void +paint_glyph_run(cairo_t *cr, + cairo_glyph_t **glyphs, + gint *n_glyphs, + PangoLayoutRun *run) +{ + gint i = 0; + gint x = 0, y = 0; + + g_assert (cr != NULL); + g_assert (glyphs != NULL); + g_assert (n_glyphs != NULL); + g_assert (run != NULL); + + if (run->glyphs != NULL && run->glyphs->num_glyphs > 0) + { + if (*n_glyphs < run->glyphs->num_glyphs) + { + *glyphs = g_realloc(*glyphs, + (sizeof(cairo_glyph_t) + * run->glyphs->num_glyphs)); + *n_glyphs = run->glyphs->num_glyphs; + } + + g_assert (*glyphs != NULL); + + for (i = 0; i < run->glyphs->num_glyphs; ++i) + { + (*glyphs)[i].index = run->glyphs->glyphs[i].glyph; + + (*glyphs)[i].x = + ((double) (x + run->glyphs->glyphs[i].geometry.x_offset)) + / ((double) PANGO_SCALE); + + (*glyphs)[i].y = + ((double) (y + run->glyphs->glyphs[i].geometry.y_offset)) + / ((double) PANGO_SCALE); + + x += run->glyphs->glyphs[i].geometry.width; + } + cairo_show_glyphs (cr, *glyphs, run->glyphs->num_glyphs); + } +} + /* GetOutline code follows ****************************/ /********* Freetype callback functions *****************************/ -static int _moveTo( FT_Vector* to, +static int _moveTo( const FT_Vector* to, void *p) { JNIEnv *env; @@ -233,7 +357,7 @@ static int _moveTo( FT_Vector* to, return 0; } -static int _lineTo( FT_Vector* to, +static int _lineTo( const FT_Vector* to, void *p) { JNIEnv *env; @@ -255,8 +379,8 @@ static int _lineTo( FT_Vector* to, return 0; } -static int _quadTo( FT_Vector* cp, - FT_Vector* to, +static int _quadTo( const FT_Vector* cp, + const FT_Vector* to, void *p) { JNIEnv *env; @@ -280,9 +404,9 @@ static int _quadTo( FT_Vector* cp, return 0; } -static int _curveTo( FT_Vector* cp1, - FT_Vector* cp2, - FT_Vector* to, +static int _curveTo( const FT_Vector* cp1, + const FT_Vector* cp2, + const FT_Vector* to, void *p) { JNIEnv *env; @@ -320,10 +444,10 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_getOutline PangoLayoutLine *current_line; FT_Outline_Funcs ftCallbacks = { - _moveTo, - _lineTo, - _quadTo, - _curveTo, + (FT_Outline_MoveToFunc) _moveTo, + (FT_Outline_LineToFunc) _lineTo, + (FT_Outline_ConicToFunc) _quadTo, + (FT_Outline_CubicToFunc) _curveTo, 0, 0 }; diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c index f44361972..ef9ac1207 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c @@ -56,17 +56,3 @@ Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_create gdk_threads_leave (); } - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_realize (JNIEnv *env, jobject obj) -{ - void *ptr; - - gdk_threads_enter (); - - ptr = NSA_GET_PTR (env, obj); - - gtk_widget_realize (GTK_WIDGET (ptr)); - - gdk_threads_leave (); -} diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c index cb2c87238..7ce1185a4 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c @@ -242,14 +242,7 @@ clipboard_get_func (GtkClipboard *clipboard, pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage); if (pixbuf != NULL) - { - gtk_selection_data_set_pixbuf (selection, pixbuf); - - /* if the GtkImage is offscreen, this is a temporary pixbuf - which should be thrown out. */ - if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE) - gdk_pixbuf_unref (pixbuf); - } + gtk_selection_data_set_pixbuf (selection, pixbuf); } else if (info == URI_TARGET) { diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c index b0d4ab9b0..4cd80a73f 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c @@ -204,6 +204,7 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursorUnlocked { void *ptr; GtkWidget *widget; + GdkWindow *win; GdkCursorType gdk_cursor_type; GdkCursor *gdk_cursor; @@ -255,16 +256,20 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetCursorUnlocked } widget = get_widget(GTK_WIDGET(ptr)); - + + win = widget->window; + if ((widget->window) == NULL) + win = GTK_WIDGET(ptr)->window; + if (image == NULL) gdk_cursor = gdk_cursor_new (gdk_cursor_type); else gdk_cursor - = gdk_cursor_new_from_pixbuf (gdk_drawable_get_display (widget->window), + = gdk_cursor_new_from_pixbuf (gdk_drawable_get_display (win), cp_gtk_image_get_pixbuf (env, image), x, y); - gdk_window_set_cursor (widget->window, gdk_cursor); + gdk_window_set_cursor (win, gdk_cursor); gdk_cursor_unref (gdk_cursor); /* Make sure the cursor is replaced on screen. */ @@ -749,6 +754,20 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetSetForeground } JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GtkComponentPeer_realize (JNIEnv *env, jobject obj) +{ + void *ptr; + + gdk_threads_enter (); + + ptr = NSA_GET_PTR (env, obj); + + gtk_widget_realize (GTK_WIDGET (ptr)); + + gdk_threads_leave (); +} + +JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_setVisibleNative (JNIEnv *env, jobject obj, jboolean visible) { @@ -793,30 +812,6 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isEnabled } JNIEXPORT jboolean JNICALL -Java_gnu_java_awt_peer_gtk_GtkComponentPeer_isRealized - (JNIEnv *env, jobject obj) -{ - void *ptr; - jboolean ret_val; - - gdk_threads_enter (); - - ptr = NSA_GET_PTR (env, obj); - - if (ptr == NULL) - { - gdk_threads_leave (); - return FALSE; - } - - ret_val = GTK_WIDGET_REALIZED (get_widget(GTK_WIDGET (ptr))); - - gdk_threads_leave (); - - return ret_val; -} - -JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_modalHasGrab (JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused))) { diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c index c60f48f51..766964314 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c @@ -186,10 +186,5 @@ Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImage gtk_window_set_icon (GTK_WINDOW (ptr), pixbuf); - /* if the GtkImage is offscreen, this is a temporary pixbuf which should - be thrown out. */ - if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE) - gdk_pixbuf_unref (pixbuf); - gdk_threads_leave (); } diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c index 92bc09edd..24e3d6317 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c @@ -37,8 +37,10 @@ exception statement from your version. */ #include "jcl.h" #include "gtkpeer.h" +#include <cairo-xlib.h> +#include <gdk/gdkx.h> + #include "gnu_java_awt_peer_gtk_GtkImage.h" -#include <gdk-pixbuf/gdk-pixbuf.h> /* The constant fields in java.awt.Image */ #define SCALE_DEFAULT 1 @@ -49,13 +51,11 @@ exception statement from your version. */ /* local stuff */ static GdkInterpType mapHints(jint hints); -static jboolean offScreen (JNIEnv * env, jobject obj); -static void *getData (JNIEnv * env, jobject obj); static void createRawData (JNIEnv * env, jobject obj, void *ptr); static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height); /** - * Loads a pixmap from a file. + * Loads a pixbuf from a file. */ JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf @@ -135,7 +135,7 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf (JNIEnv *env, jobject obj) { int width, heigth; - GdkPixbuf *pixbuf = (GdkPixbuf *) getData (env, obj); + GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj); width = gdk_pixbuf_get_width (pixbuf); heigth = gdk_pixbuf_get_height (pixbuf); setWidthHeight(env, obj, width, heigth); @@ -154,6 +154,8 @@ Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj) jint *result_array_iter, *dst; int i,j; + gdk_threads_enter (); + pixbuf = cp_gtk_image_get_pixbuf (env, obj); width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); @@ -190,11 +192,9 @@ Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj) } } - if (offScreen (env, obj) == JNI_TRUE) - gdk_pixbuf_unref (pixbuf); - (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0); + gdk_threads_leave (); return result_array; } @@ -206,7 +206,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj, jintArray pixels) { - GdkPixbuf *pixbuf = (GdkPixbuf *)getData (env, obj); + GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj); int width, height, rowstride; guchar *pixeldata; jint *src_array_iter, *src; @@ -231,10 +231,10 @@ Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj, } /** - * Allocates a Gtk Pixbuf or Pixmap. + * Allocates a Gtk Pixbuf */ JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj) +Java_gnu_java_awt_peer_gtk_GtkImage_createPixbuf(JNIEnv *env, jobject obj) { int width, height; jclass cls; @@ -249,35 +249,58 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj) g_assert (field != 0); height = (*env)->GetIntField (env, obj, field); - if (offScreen (env, obj) == JNI_FALSE) - createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB, - TRUE, - 8, - width, - height)); - else - createRawData (env, obj, gdk_pixmap_new (NULL, width, height, - gdk_rgb_get_visual ()->depth)); + createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB, + TRUE, + 8, + width, + height)); +} + +/** + * Allocates a Gtk Pixbuf + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GtkImage_initFromBuffer(JNIEnv *env, jobject obj, + jlong bufferPointer) +{ + int width, height; + jclass cls; + jfieldID field; + GdkPixbuf *pixbuf; + const guchar *bp = JLONG_TO_PTR(const guchar, bufferPointer); + + g_assert(bp != NULL); + cls = (*env)->GetObjectClass( env, obj ); + field = (*env)->GetFieldID( env, cls, "width", "I" ); + g_assert( field != 0 ); + width = (*env)->GetIntField( env, obj, field ); + + field = (*env)->GetFieldID( env, cls, "height", "I" ); + g_assert( field != 0 ); + height = (*env)->GetIntField( env, obj, field ); + + pixbuf = gdk_pixbuf_new_from_data( bp, + GDK_COLORSPACE_RGB, TRUE, 8, + width, height, width * 4, NULL, NULL ); + g_assert( pixbuf != NULL ); + createRawData( env, obj, pixbuf ); } /** - * Frees the Gtk Pixmap. + * Frees the Gtk Pixbuf. */ JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkImage_freePixmap(JNIEnv *env, jobject obj) +Java_gnu_java_awt_peer_gtk_GtkImage_freePixbuf(JNIEnv *env, jobject obj) { - if (offScreen (env, obj) == JNI_FALSE) - gdk_pixbuf_unref ((GdkPixbuf *)getData (env, obj)); - else - g_object_unref ((GdkPixmap *)getData (env, obj)); + gdk_pixbuf_unref (cp_gtk_image_get_pixbuf (env, obj)); } /** - * Sets this pixmap to a scaled version of the source pixmap. + * Sets this to a scaled version of the original pixbuf * width and height of the destination GtkImage must be set. */ JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env, +Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixbuf(JNIEnv *env, jobject destination, jobject source, jint hints) @@ -304,251 +327,25 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env, width, height, mapHints(hints)); - if (offScreen (env, source) == JNI_TRUE) - gdk_pixbuf_unref (pixbuf); - createRawData (env, destination, (void *)dst); } /** - * Draws the pixbuf at x, y, scaled to width and height and - * optionally composited with a given background color. - */ -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaled - (JNIEnv *env, jobject obj, jobject gc_obj, - jint bg_red, jint bg_green, jint bg_blue, - jint x, jint y, jint width, jint height, jboolean composite) -{ - GdkPixbuf* dst; - struct graphics *g; - guint32 bgColor; - - gdk_threads_enter (); - - if (width <= 0 || height <= 0) - { - gdk_threads_leave (); - return; - } - - bgColor = ((bg_red & 0xFF) << 16) | - ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF); - - g = (struct graphics *) NSA_GET_G_PTR (env, gc_obj); - - if (!g || !GDK_IS_DRAWABLE (g->drawable)) - { - gdk_threads_leave (); - return; - } - - if (offScreen (env, obj) == JNI_FALSE) - { - GdkPixbuf* pixbuf = (GdkPixbuf *)getData (env, obj); - - /* Scale and composite the image */ - if (composite == JNI_TRUE) - dst = gdk_pixbuf_composite_color_simple (pixbuf, - width, - height, - GDK_INTERP_BILINEAR, - 255, - width, - bgColor, - bgColor); - else - dst = gdk_pixbuf_scale_simple(pixbuf, - width, height, - GDK_INTERP_BILINEAR); - - gdk_draw_pixbuf (g->drawable, - g->gc, - dst, - 0, 0, - x + g->x_offset, y + g->y_offset, - width, height, - GDK_RGB_DITHER_NORMAL, 0, 0); - gdk_pixbuf_unref (dst); - - } else { - /* Get a pixmap */ - GdkPixmap* pixmap = (GdkPixmap *)getData (env, obj); - gdk_draw_drawable (g->drawable, - g->gc, - pixmap, - 0, 0, /* src x,y */ - x + g->x_offset, y + g->y_offset, - width, height); - } - - gdk_threads_leave (); -} - -/** - * Draws the pixbuf at x, y, scaled to width and height and - * optionally composited and/or flipped with a given background color. - */ -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped -(JNIEnv *env, jobject obj, jobject gc_obj, - jint bg_red, jint bg_green, jint bg_blue, -#if GTK_MINOR_VERSION > 4 - jboolean flipx, jboolean flipy, -#else - jboolean flipx __attribute__((unused)), - jboolean flipy __attribute__((unused)), -#endif - jint srcx, jint srcy, jint srcwidth, jint srcheight, - jint dstx, jint dsty, jint dstwidth, jint dstheight, - jboolean composite) -{ - GdkPixbuf *pixbuf; - GdkPixbuf *tmp, *dst; - struct graphics *g; - guint32 bgColor; - - gdk_threads_enter (); - - if (srcwidth <= 0 || srcheight <= 0 - || dstwidth <= 0 || dstheight <= 0) - { - gdk_threads_leave (); - return; - } - - bgColor = ((bg_red & 0xFF) << 16) | - ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF); - - g = (struct graphics *) NSA_GET_G_PTR (env, gc_obj); - - if (!g || !GDK_IS_DRAWABLE (g->drawable)) - { - gdk_threads_leave (); - return; - } - - if (offScreen (env, obj) == JNI_FALSE) - { - pixbuf = (GdkPixbuf *)getData (env, obj); - - /* Get the source area */ - tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - TRUE, - 8, - srcwidth, - srcheight); - - gdk_pixbuf_copy_area (pixbuf, - srcx, srcy, - srcwidth, srcheight, - tmp, - 0, 0); /* dst x , dst y */ - } else { - /* Get a pixbuf from the pixmap */ - GdkDrawable *pixmap = (GdkDrawable *)getData(env, obj); - tmp = gdk_pixbuf_get_from_drawable (NULL, - pixmap, - gdk_drawable_get_colormap( pixmap ), - srcx, srcy, - 0, 0, /* dst x , dst y */ - srcwidth, srcheight); - } - - /* FIXME: This #if should be discarded once I feel comfortable about - GTK 2.6 dependence */ -#if GTK_MINOR_VERSION > 4 - /* Flip it if necessary. */ - if (flipx == JNI_TRUE) - { - GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, TRUE); - gdk_pixbuf_unref (tmp); - tmp = tmp2; - } - if (flipy == JNI_TRUE) - { - GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, FALSE); - gdk_pixbuf_unref (tmp); - tmp = tmp2; - } -#endif - - /* Scale and composite the image */ - if (composite == JNI_TRUE) - dst = gdk_pixbuf_composite_color_simple (tmp, - dstwidth, - dstheight, - GDK_INTERP_BILINEAR, - 255, - dstwidth, - bgColor, - bgColor); - else - dst = gdk_pixbuf_scale_simple(tmp, - dstwidth, dstheight, - GDK_INTERP_BILINEAR); - gdk_pixbuf_unref (tmp); - - gdk_draw_pixbuf (g->drawable, - g->gc, - dst, - 0, 0, - dstx + g->x_offset, dsty + g->y_offset, - dstwidth, dstheight, - GDK_RGB_DITHER_NORMAL, 0, 0); - - gdk_pixbuf_unref (dst); - - gdk_threads_leave (); -} - -/** * Used by GtkFramePeer */ GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj) { - int width, height; - GdkPixbuf *pixbuf; - GdkPixmap* pixmap; jclass cls; - jfieldID field; - - if (offScreen (env, obj) == JNI_FALSE) - return (GdkPixbuf *)getData (env, obj); + jfieldID data_fid; + jobject data; cls = (*env)->GetObjectClass (env, obj); - field = (*env)->GetFieldID (env, cls, "width", "I"); - g_assert (field != 0); - width = (*env)->GetIntField (env, obj, field); - - field = (*env)->GetFieldID (env, cls, "height", "I"); - g_assert (field != 0); - height = (*env)->GetIntField (env, obj, field); - - /* Get a pixmap */ - pixmap = (GdkPixmap *)getData (env, obj); - pixbuf = gdk_pixbuf_get_from_drawable (NULL, - pixmap, - gdk_drawable_get_colormap( pixmap ), - 0, 0, /* src x , src y */ - 0, 0, /* dst x , dst y */ - width, height); - return pixbuf; -} - -/** - * Used by GdkGraphics - */ -GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj) -{ - if (offScreen (env, obj) == JNI_FALSE) - return NULL; - return (GdkPixmap *)getData (env, obj); -} + data_fid = (*env)->GetFieldID (env, cls, "pixbuf", + "Lgnu/classpath/Pointer;"); + g_assert (data_fid != 0); + data = (*env)->GetObjectField (env, obj, data_fid); -jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj) -{ - return offScreen(env, obj); + return (GdkPixbuf *)JCL_GetRawData (env, data); } /** @@ -593,18 +390,6 @@ static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height) (*env)->SetIntField (env, obj, field, (jint)height); } -/* Returns the value of the offScreen field. */ -static jboolean offScreen (JNIEnv *env, jobject obj) -{ - jclass cls; - jfieldID field; - - cls = (*env)->GetObjectClass (env, obj); - field = (*env)->GetFieldID (env, cls, "offScreen", "Z"); - g_assert (field != 0); - return (*env)->GetBooleanField (env, obj, field); -} - /* Store and get the pixbuf pointer */ static void createRawData (JNIEnv * env, jobject obj, void *ptr) @@ -614,7 +399,7 @@ createRawData (JNIEnv * env, jobject obj, void *ptr) jfieldID data_fid; cls = (*env)->GetObjectClass (env, obj); - data_fid = (*env)->GetFieldID (env, cls, "pixmap", + data_fid = (*env)->GetFieldID (env, cls, "pixbuf", "Lgnu/classpath/Pointer;"); g_assert (data_fid != 0); @@ -623,18 +408,3 @@ createRawData (JNIEnv * env, jobject obj, void *ptr) (*env)->SetObjectField (env, obj, data_fid, data); } -static void * -getData (JNIEnv * env, jobject obj) -{ - jclass cls; - jfieldID data_fid; - jobject data; - - cls = (*env)->GetObjectClass (env, obj); - data_fid = (*env)->GetFieldID (env, cls, "pixmap", - "Lgnu/classpath/Pointer;"); - g_assert (data_fid != 0); - data = (*env)->GetObjectField (env, obj, data_fid); - - return JCL_GetRawData (env, data); -} diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c index b14330e5f..c966f6331 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c @@ -185,10 +185,6 @@ Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkInit (JNIEnv *env, old_glog_func = g_log_set_default_handler (&glog_func, NULL); #endif -#if GTK_CAIRO - cp_gtk_graphics2d_init_jni (); -#endif - cp_gtk_graphics_init_jni (); cp_gtk_button_init_jni (); cp_gtk_checkbox_init_jni (); cp_gtk_choice_init_jni (); diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c new file mode 100644 index 000000000..0234943b2 --- /dev/null +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c @@ -0,0 +1,190 @@ +/* gnu_java_awt_peer_gtk_VolatileImage.c + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +#include "jcl.h" +#include "gtkpeer.h" +#include <gdk/gdkx.h> +#include <gdk/gdktypes.h> +#include <gdk/gdkprivate.h> +#include <gdk/gdkx.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gdk-pixbuf/gdk-pixdata.h> + +#include "gnu_java_awt_peer_gtk_GtkVolatileImage.h" +#include "cairographics2d.h" + +/* prototypes */ +static void *getNativeObject( JNIEnv *env, jobject obj ); +/* static void setNativeObject( JNIEnv *env, jobject obj, void *ptr ); */ + +GdkPixmap *cp_gtk_get_pixmap( JNIEnv *env, jobject obj); + +/** + * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha. + */ +JNIEXPORT jlong JNICALL +Java_gnu_java_awt_peer_gtk_GtkVolatileImage_init (JNIEnv *env, + jobject obj __attribute__ ((__unused__)), + jobject peer, + jint width, jint height) +{ + GtkWidget *widget = NULL; + GdkPixmap* pixmap; + void *ptr = NULL; + + gdk_threads_enter(); + + if( peer != NULL ) + { + ptr = NSA_GET_PTR (env, peer); + g_assert (ptr != NULL); + + widget = GTK_WIDGET (ptr); + g_assert (widget != NULL); + pixmap = gdk_pixmap_new( widget->window, width, height, -1 ); + } + else + pixmap = gdk_pixmap_new( NULL, width, height, 16 ); + + gdk_threads_leave(); + + g_assert( pixmap != NULL ); + + return PTR_TO_JLONG( pixmap ); +} + +/** + * Destroy the surface + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GtkVolatileImage_destroy (JNIEnv *env, jobject obj) +{ + GdkPixmap* pixmap = getNativeObject(env, obj); + if( pixmap != NULL ) + { + gdk_threads_enter(); + g_object_unref( pixmap ); + gdk_threads_leave(); + } +} + +/** + * Gets all pixels in an array + */ +JNIEXPORT jintArray JNICALL +Java_gnu_java_awt_peer_gtk_GtkVolatileImage_getPixels +(JNIEnv *env, jobject obj) +{ + /* jint *pixeldata, *jpixdata; */ + jint *jpixdata; + GdkPixmap *pixmap; + jintArray jpixels; + int width, height, depth, size; + jclass cls; + jfieldID field; + + cls = (*env)->GetObjectClass (env, obj); + field = (*env)->GetFieldID (env, cls, "width", "I"); + g_assert (field != 0); + width = (*env)->GetIntField (env, obj, field); + + field = (*env)->GetFieldID (env, cls, "height", "I"); + g_assert (field != 0); + height = (*env)->GetIntField (env, obj, field); + + pixmap = GDK_PIXMAP(getNativeObject(env, obj)); + g_assert(pixmap != NULL); + + gdk_threads_enter(); + + /* get depth in bytes */ + depth = gdk_drawable_get_depth( pixmap ) >> 3; + size = width * height * 4; + jpixels = (*env)->NewIntArray ( env, size ); + jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL); + /* memcpy (jpixdata, pixeldata, size * sizeof( jint )); */ + + (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0); + + gdk_threads_leave(); + + return jpixels; +} + +/** + * Update the pixels. + */ +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GtkVolatileImage_update +(JNIEnv *env, jobject obj, jobject gtkimage) +{ + GdkPixmap *pixmap = getNativeObject(env, obj); + GdkPixbuf *pixbuf; + + gdk_threads_enter(); + g_assert( pixmap != NULL ); + + pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage); + g_assert( pixbuf != NULL ); + + gdk_draw_pixbuf (pixmap, NULL, pixbuf, + 0, 0, 0, 0, /* src and dest x, y */ + -1, -1, /* full width, height */ + GDK_RGB_DITHER_NORMAL, 0, 0); + gdk_threads_leave(); +} + +GdkPixmap *cp_gtk_get_pixmap( JNIEnv *env, jobject obj) +{ + return (GdkPixmap *)getNativeObject(env, obj); +} + +/** + * Gets the native object field. + */ +static void * +getNativeObject( JNIEnv *env, jobject obj ) +{ + jclass cls; + jlong value; + jfieldID nofid; + cls = (*env)->GetObjectClass( env, obj ); + nofid = (*env)->GetFieldID( env, cls, "nativePointer", "J" ); + value = (*env)->GetLongField( env, obj, nofid ); + (*env)->DeleteLocalRef( env, cls ); + return JLONG_TO_PTR(void, value); +} diff --git a/native/jni/gtk-peer/gtkcairopeer.h b/native/jni/gtk-peer/gtkcairopeer.h deleted file mode 100644 index dee843c8a..000000000 --- a/native/jni/gtk-peer/gtkcairopeer.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef __GTKCAIROPEER_H__ -#define __GTKCAIROPEER_H__ - -/* gtkcairopeer.h -- Some global variables and #defines - Copyright (C) 1998, 1999 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -#include "gtkpeer.h" -#include <cairo.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -/* - A graphics2d struct is both simpler and uglier than a graphics - struct. - - Most of the graphics2d drawing state is held in the referenced cairo_t - and corresponding cairo_surface_t, so we can ignore it. - - In addition to the cairo_t, we need to hold an extra reference to the - underlying GdkDrawable so its refcount matches the lifecycle of the java - Graphics object which is peering with us; also a reference to a byte - buffer and cairo_surface_t which contain the pattern you're drawing from - (if it exists). - - Finally, it is possible that we are using a non-RENDER capable X server, - therefore we will be drawing to an cairo_surface_t which is actually a - pixbuf. When this is the case, the pointer to a GdkPixbuf will be - non-NULL and any drawing operation needs to be bracketed by pixbuf - load/save operations. If the GdkPixbuf pointer is NULL, we will treat - the cairo_surface_t as RENDER-capable. - */ - -struct graphics2d -{ - cairo_t *cr; - cairo_surface_t *surface; - GdkDrawable *drawable; - GdkWindow *win; - GdkPixbuf *drawbuf; - char *pattern_pixels; - cairo_surface_t *pattern_surface; - cairo_pattern_t *pattern; - gboolean debug; - enum - { - MODE_DRAWABLE_WITH_RENDER, - MODE_DRAWABLE_NO_RENDER, - MODE_JAVA_ARRAY - } - mode; - - /* Support for MODE_JAVA_ARRAY */ - jintArray jarray; - jint width, height; - jint *javabuf; - jint *javabuf_copy; - jboolean isCopy; -}; - -#endif /* __GTKCAIROPEER_H */ diff --git a/native/jni/gtk-peer/gtkpeer.h b/native/jni/gtk-peer/gtkpeer.h index 9a1590b81..065d20608 100644 --- a/native/jni/gtk-peer/gtkpeer.h +++ b/native/jni/gtk-peer/gtkpeer.h @@ -36,12 +36,14 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#include <cairo.h> #include <gtk/gtk.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <config.h> #include "native_state.h" +#include <gdk-pixbuf/gdk-pixbuf.h> #include <jni.h> @@ -54,6 +56,7 @@ exception statement from your version. */ extern struct state_table *cp_gtk_native_state_table; extern struct state_table *cp_gtk_native_global_ref_table; +extern struct state_table *cp_gtk_native_graphics2d_state_table; #define NSA_INIT(env, clazz) \ do {cp_gtk_native_state_table = cp_gtk_init_state_table (env, clazz); \ @@ -83,34 +86,21 @@ extern struct state_table *cp_gtk_native_global_ref_table; (*env)->DeleteGlobalRef (env, *globRefPtr); \ free (globRefPtr);} while (0) -extern struct state_table *cp_gtk_native_graphics_state_table; +#define NSA_G2D_INIT(env, clazz) \ + cp_gtk_native_graphics2d_state_table = cp_gtk_init_state_table (env, clazz) -#define NSA_G_INIT(env, clazz) \ - cp_gtk_native_graphics_state_table = cp_gtk_init_state_table (env, clazz) +#define NSA_GET_G2D_PTR(env, obj) \ + cp_gtk_get_state (env, obj, cp_gtk_native_graphics2d_state_table) -#define NSA_GET_G_PTR(env, obj) \ - cp_gtk_get_state (env, obj, cp_gtk_native_graphics_state_table) +#define NSA_SET_G2D_PTR(env, obj, ptr) \ + cp_gtk_set_state (env, obj, cp_gtk_native_graphics2d_state_table, (void *)ptr) -#define NSA_SET_G_PTR(env, obj, ptr) \ - cp_gtk_set_state (env, obj, cp_gtk_native_graphics_state_table, (void *)ptr) - -#define NSA_DEL_G_PTR(env, obj) \ - cp_gtk_remove_state_slot (env, obj, cp_gtk_native_graphics_state_table) +#define NSA_DEL_G2D_PTR(env, obj) \ + cp_gtk_remove_state_slot (env, obj, cp_gtk_native_graphics2d_state_table) #define SWAPU32(w) \ (((w) << 24) | (((w) & 0xff00) << 8) | (((w) >> 8) & 0xff00) | ((w) >> 24)) -struct graphics -{ - GdkDrawable *drawable; - GdkGC *gc; - GdkColormap *cm; - PangoFontDescription *pango_font; - PangoContext *pango_context; - PangoLayout *pango_layout; - jint x_offset, y_offset; -}; - /* New-style event masks. */ #define AWT_BUTTON1_DOWN_MASK (1 << 10) #define AWT_BUTTON2_DOWN_MASK (1 << 11) @@ -192,14 +182,12 @@ jint cp_gtk_state_to_awt_mods (guint state); /* Image helpers */ GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj); -GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj); -jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj); + +/* Component Graphics helpers */ +void cp_gtk_grab_current_drawable(GtkWidget *widget, GdkDrawable **draw, + GdkWindow **win); /* JNI initialization functions */ -#if GTK_CAIRO -void cp_gtk_graphics2d_init_jni (void); -#endif -void cp_gtk_graphics_init_jni (void); void cp_gtk_button_init_jni (void); void cp_gtk_checkbox_init_jni (void); void cp_gtk_choice_init_jni (void); @@ -221,6 +209,8 @@ void cp_gtk_textcomponent_connect_signals (GObject *ptr, jobject *gref); /* Debugging */ void cp_gtk_print_current_thread (void); +GdkPixmap *cp_gtk_get_pixmap( JNIEnv *env, jobject obj); + #define SYNCHRONIZE_GDK 0 #define DEBUG_LOCKING 0 |