aboutsummaryrefslogtreecommitdiff
path: root/libjava/jni
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@redhat.com>2003-10-25 18:41:45 +0000
committerGraydon Hoare <graydon@gcc.gnu.org>2003-10-25 18:41:45 +0000
commitc4bcf1418f3057826922bb830d3ee6aaf73adc1d (patch)
treea86497db03f846687cb8c6b5f16cc08c970a7a17 /libjava/jni
parent11f9a0ed8f5cdd0214075bc8501a91c06a835d2a (diff)
downloadgcc-c4bcf1418f3057826922bb830d3ee6aaf73adc1d.zip
gcc-c4bcf1418f3057826922bb830d3ee6aaf73adc1d.tar.gz
gcc-c4bcf1418f3057826922bb830d3ee6aaf73adc1d.tar.bz2
ClasspathToolkit.java: New abstract class.
2003-10-14 Graydon Hoare <graydon@redhat.com> * gnu/java/awt/ClasspathToolkit.java: New abstract class. * gnu/java/awt/peer/ClasspathFontPeer.java: New abstract class. * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c: New concrete implementation of ClasspathFontPeer, with native part. * gnu/java/awt/peer/gtk/GdkGlyphVector.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c: New class, with native part. * gnu/java/awt/peer/gtk/GdkGraphics2D.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c: implement setFont, cairoSetFont, drawGlyphVector, cairoShowGlyphs. From-SVN: r72931
Diffstat (limited to 'libjava/jni')
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c160
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c571
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c95
3 files changed, 819 insertions, 7 deletions
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
new file mode 100644
index 0000000..092979b
--- /dev/null
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
@@ -0,0 +1,160 @@
+/* gnu_java_awt_GdkFont.c
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 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 "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkClasspathFontPeer.h"
+
+struct state_table *native_font_state_table;
+
+/*
+rough sketch of the mapping between java and
+pango text objects:
+
+ Font <-> - PangoFont
+ - PangoFontDescription
+ - PangoContext
+
+ GlyphVector <-> - GList of PangoGlyphItem
+ - PangoFontDescription
+ - PangoContext
+
+ FontRenderContext <-> stays in plain java
+
+*/
+
+enum java_awt_font_style {
+ java_awt_font_PLAIN = 0,
+ java_awt_font_BOLD = 1,
+ java_awt_font_ITALIC = 2
+};
+
+enum java_awt_font_baseline {
+ java_awt_font_ROMAN_BASELINE = 0,
+ java_awt_font_CENTER_BASELINE = 1,
+ java_awt_font_HANGING_BASELINE = 2
+};
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ NSA_FONT_INIT (env, clazz);
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_initState
+ (JNIEnv *env, jobject self)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
+ g_assert (pfont != NULL);
+ NSA_SET_FONT_PTR (env, self, pfont);
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_dispose
+ (JNIEnv *env, jobject self)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+ pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self);
+ g_assert (pfont != NULL);
+ if (pfont->ctx != NULL)
+ g_object_unref (pfont->ctx);
+ if (pfont->font != NULL)
+ g_object_unref (pfont->font);
+ if (pfont->desc != NULL)
+ pango_font_description_free (pfont->desc);
+ g_free (pfont);
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_setFont
+ (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size)
+{
+ struct peerfont *pfont = NULL;
+ PangoFontMap *map = NULL;
+ char const *family_name = NULL;
+
+ gdk_threads_enter ();
+ enum java_awt_font_style style = (enum java_awt_font_style) style_int;
+
+ g_assert (self != NULL);
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
+ g_assert (pfont != NULL);
+
+ pfont->desc = pango_font_description_new ();
+ g_assert (pfont->desc != NULL);
+
+ family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
+ g_assert (family_name != NULL);
+ pango_font_description_set_family (pfont->desc, family_name);
+ (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
+
+ pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
+
+ if (style & java_awt_font_BOLD)
+ pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
+
+ if (style & java_awt_font_ITALIC)
+ pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
+
+ /*
+ FIXME: these are possibly wrong, and should in any case
+ probably be cached between calls.
+ */
+
+ map = pango_ft2_font_map_for_display ();
+ g_assert (map != NULL);
+
+ if (pfont->ctx == NULL)
+ pfont->ctx = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (map));
+ g_assert (pfont->ctx != NULL);
+
+ if (pfont->font != NULL)
+ g_object_unref (pfont->font);
+
+ pfont->font = pango_font_map_load_font (map, pfont->ctx, pfont->desc);
+ g_assert (pfont->font != NULL);
+
+ gdk_threads_leave ();
+}
+
+
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
new file mode 100644
index 0000000..052f7e9
--- /dev/null
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
@@ -0,0 +1,571 @@
+/* gdkglyphvector.c
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 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 "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkGlyphVector.h"
+
+struct state_table *native_glyphvector_state_table;
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ NSA_GV_INIT (env, clazz);
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initState
+ (JNIEnv *env, jobject self, jobject font, jobject ctx)
+{
+ struct glyphvec *vec = NULL;
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+ g_assert (font != NULL);
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+ g_assert (pfont->ctx != NULL);
+ g_assert (pfont->desc != NULL);
+
+ g_assert (self != NULL);
+ vec = (struct glyphvec *) g_malloc0 (sizeof (struct glyphvec));
+ g_assert (vec != NULL);
+
+ vec->desc = pango_font_description_copy (pfont->desc);
+ g_assert (vec->desc != NULL);
+
+ vec->ctx = pfont->ctx;
+ g_object_ref (vec->ctx);
+
+ NSA_SET_GV_PTR (env, self, vec);
+ gdk_threads_leave ();
+}
+
+static void free_glyphitems (GList *list)
+{
+ GList *i = NULL;
+ PangoGlyphItem *gi = NULL;
+
+ for (i = g_list_first (list); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+
+ if (gi->glyphs != NULL)
+ pango_glyph_string_free (gi->glyphs);
+
+ if (gi->item != NULL)
+ g_free (gi->item);
+ }
+ g_list_free (list);
+}
+
+static void seek_glyphstring_idx (GList *list, int idx,
+ int *nidx,
+ PangoGlyphString **gs,
+ PangoFont **fnt)
+{
+ GList *i = NULL;
+ PangoGlyphItem *gi = NULL;
+
+ g_assert (list != NULL);
+ g_assert (gs != NULL);
+ g_assert (nidx != NULL);
+
+ int begin = 0;
+ for (i = g_list_first (list); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+
+ g_assert (gi->glyphs != NULL);
+
+ if (begin <= idx && idx < begin + gi->glyphs->num_glyphs)
+ {
+ *gs = gi->glyphs;
+ *nidx = idx - begin;
+ if (fnt && gi->item)
+ *fnt = gi->item->analysis.font;
+ return;
+ }
+ else
+ {
+ begin += gi->glyphs->num_glyphs;
+ }
+ }
+ *gs = NULL;
+ *nidx = -1;
+}
+
+static void seek_glyph_idx (GList *list, int idx,
+ PangoGlyphInfo **g,
+ PangoFont **fnt)
+{
+ PangoGlyphString *gs = NULL;
+ int nidx = -1;
+
+ g_assert (list != NULL);
+ g_assert (g != NULL);
+
+ seek_glyphstring_idx (list, idx, &nidx, &gs, fnt);
+
+ g_assert (gs != NULL);
+ g_assert (nidx != -1);
+ g_assert (nidx < gs->num_glyphs);
+ g_assert (gs->glyphs != NULL);
+
+ *g = gs->glyphs + nidx;
+}
+
+static void union_rects (PangoRectangle *r1,
+ const PangoRectangle *r2)
+{
+ PangoRectangle r;
+
+ g_assert (r1 != NULL);
+ g_assert (r2 != NULL);
+
+ /*
+ x is the left edge of the rect,
+ y is the top edge of the rect
+ */
+
+#ifndef min
+#define min(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
+#ifndef max
+#define max(x,y) ((x) < (y) ? (y) : (x))
+#endif
+
+ r.x = min(r1->x, r2->x);
+
+ r.y = min(r1->y, r2->y);
+
+ r.width = max(r1->x + r1->width,
+ r2->x + r2->width) - r.x;
+
+ r.height = max(r1->y + r1->height,
+ r2->y + r2->height) - r.y;
+
+ *r1 = r;
+}
+
+static jdoubleArray rect_to_array (JNIEnv *env, const PangoRectangle *r)
+{
+ /* We often return rectangles as arrays : { x, y, w, h } */
+ jdoubleArray ret;
+ double *rp = NULL;
+ g_assert (r != NULL);
+ ret = (*env)->NewDoubleArray (env, 4);
+ rp = (*env)->GetDoubleArrayElements (env, ret, NULL);
+ g_assert (rp != NULL);
+ rp[0] = r->x / (double)PANGO_SCALE;
+ /* freetype and pango's view of space is upside down from java2d's */
+ rp[1] = (r->y / (double)PANGO_SCALE) * -1;
+ rp[2] = r->width / (double)PANGO_SCALE;
+ rp[3] = r->height / (double)PANGO_SCALE;
+ (*env)->ReleaseDoubleArrayElements (env, ret, rp, 0);
+ return ret;
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_dispose
+ (JNIEnv *env, jobject self)
+{
+ struct glyphvec *vec = NULL;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_DEL_GV_PTR (env, self);
+ g_assert (vec != NULL);
+
+ if (vec->glyphitems != NULL)
+ {
+ free_glyphitems (vec->glyphitems);
+ vec->glyphitems = NULL;
+ }
+
+ if (vec->desc != NULL)
+ pango_font_description_free (vec->desc);
+
+ if (vec->ctx != NULL)
+ g_object_unref (vec->ctx);
+
+ g_free (vec);
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setChars
+ (JNIEnv *env, jobject self, jstring chars)
+{
+ struct glyphvec *vec = NULL;
+ gchar *str = NULL;
+ GList *items = NULL, *item = NULL;
+ PangoGlyphItem *gi;
+ PangoAttrList *attrs = NULL;
+ gint len = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->desc != NULL);
+ g_assert (vec->ctx != NULL);
+
+ len = (*gdk_env)->GetStringUTFLength (env, chars);
+ str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
+ g_assert (str != NULL);
+
+ /* step 1: mark the text as having our FontFescription as an
+ attribute, then "itemize" the text */
+
+ attrs = pango_attr_list_new ();
+ g_assert (attrs != NULL);
+
+ PangoAttribute *da = pango_attr_font_desc_new(vec->desc);
+ g_assert (da != NULL);
+ da->start_index = 0;
+ da->end_index = len;
+
+ pango_attr_list_insert (attrs, da);
+ items = pango_itemize (vec->ctx, str, 0, len, attrs, NULL);
+ g_assert (items != NULL);
+
+ /*
+ step 2: for each item:
+ - shape the item into a glyphstring
+ - store the (item, glyphstring) pair in the vec->glyphitems list
+ */
+
+ if (vec->glyphitems != NULL)
+ {
+ free_glyphitems (vec->glyphitems);
+ vec->glyphitems = NULL;
+ }
+
+ for (item = g_list_first (items); item != NULL; item = g_list_next (item))
+ {
+ g_assert (item->data != NULL);
+
+ gi = NULL;
+ gi = g_malloc0 (sizeof(PangoGlyphItem));
+ g_assert (gi != NULL);
+
+ gi->item = (PangoItem *)item->data;
+ gi->glyphs = pango_glyph_string_new ();
+ g_assert (gi->glyphs != NULL);
+
+ pango_shape (str + gi->item->offset,
+ gi->item->length,
+ &(gi->item->analysis),
+ gi->glyphs);
+
+ vec->glyphitems = g_list_append (vec->glyphitems, gi);
+ }
+
+ /*
+ ownership of each item has been transferred to glyphitems,
+ but the list should be freed.
+ */
+
+ g_list_free (items);
+ pango_attr_list_unref (attrs);
+
+ (*env)->ReleaseStringUTFChars (env, chars, str);
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setGlyphCodes
+ (JNIEnv *env, jobject self, jintArray codes)
+{
+ struct glyphvec *vec = NULL;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+
+ /*
+ FIXME: setting glyph codes doesn't seem particularly plausible at the
+ moment.
+ */
+
+ gdk_threads_leave ();
+
+}
+
+
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphCode
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoGlyphInfo *gi = NULL;
+ jint ret = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ seek_glyph_idx (vec->glyphitems, idx, &gi, NULL);
+ g_assert (gi != NULL);
+ ret = gi->glyph;
+ gdk_threads_leave ();
+
+ return (jint)(ret);
+}
+
+
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_numGlyphs
+ (JNIEnv *env, jobject self)
+{
+ GList *i = NULL;
+ PangoGlyphItem *gi = NULL;
+ struct glyphvec *vec = NULL;
+ jint count = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+
+ for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+ g_assert (gi->glyphs != NULL);
+ count += gi->glyphs->num_glyphs;
+ }
+ gdk_threads_leave ();
+
+ return count;
+}
+
+
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphCharIndex
+ (JNIEnv *env, jobject self, jint idx)
+{
+ /*
+ FIXME: this is not correct, rather it assumes a (broken) 1:1
+ glyph:char model. it can be implemented in terms of bytes (also
+ broken) using pango's current interface, or perhaps in terms of
+ characters if some better byte->character conversion operator is
+ found. for the time being we leave it broken.
+ */
+ return idx;
+}
+
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allLogicalExtents
+ (JNIEnv *env, jobject self)
+{
+ struct glyphvec *vec = NULL;
+ GList *i;
+ PangoGlyphItem *gi = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle tmp, dummy;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+ g_assert (gi->glyphs != NULL);
+
+ pango_glyph_string_extents (gi->glyphs,
+ gi->item->analysis.font,
+ &dummy,
+ &tmp);
+ union_rects (&rect, &tmp);
+ }
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allInkExtents
+ (JNIEnv *env, jobject self)
+{
+ struct glyphvec *vec = NULL;
+ GList *i;
+ PangoGlyphItem *gi = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle tmp, dummy;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+ g_assert (gi->glyphs != NULL);
+
+ pango_glyph_string_extents (gi->glyphs,
+ gi->item->analysis.font,
+ &tmp,
+ &dummy);
+ union_rects (&rect, &tmp);
+ }
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphLogicalExtents
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle dummy;
+ PangoGlyphInfo *gi = NULL;
+ PangoFont *font = NULL;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ seek_glyph_idx (vec->glyphitems, idx, &gi, &font);
+ g_assert (gi != NULL);
+ g_assert (font != NULL);
+
+ pango_font_get_glyph_extents (font, gi->glyph, &dummy, &rect);
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphInkExtents
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle dummy;
+ PangoGlyphInfo *gi = NULL;
+ PangoFont *font = NULL;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ seek_glyph_idx (vec->glyphitems, idx, &gi, &font);
+ g_assert (gi != NULL);
+ g_assert (font != NULL);
+
+ pango_font_get_glyph_extents (font, gi->glyph, &rect, &dummy);
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphIsHorizontal
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoDirection dir;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->desc != NULL);
+ g_assert (vec->ctx != NULL);
+
+ /*
+ FIXME: this is an approximation; it's not clear to me whether
+ glyphs themselves are horizontal or vertical so much as the
+ writing system or writing context. pango thinks it's a context
+ issue, so we use that for now.
+ */
+
+ dir = pango_context_get_base_dir (vec->ctx);
+
+ gdk_threads_leave ();
+
+ return
+ ((dir == PANGO_DIRECTION_LTR) ||
+ (dir == PANGO_DIRECTION_RTL));
+}
+
+
+JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_isEqual
+ (JNIEnv *env, jobject self, jobject other)
+{
+ struct glyphvec *vec1 = NULL, *vec2 = NULL;
+ jboolean eq = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec1 = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ vec2 = (struct glyphvec *)NSA_GET_GV_PTR (env, other);
+ g_assert (vec1 != NULL);
+ g_assert (vec2 != NULL);
+
+ /* FIXME: is there some more advantageous definition of equality for
+ glyph vectors? */
+ eq = (vec1 == vec2);
+
+ gdk_threads_leave ();
+ return eq;
+}
+
+
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
index 04eb2e5..08a9742 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
@@ -36,6 +36,7 @@
exception statement from your version. */
#include "gtkpeer.h"
+#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
#include <gdk/gdktypes.h>
#include <gdk/gdkprivate.h>
@@ -45,6 +46,8 @@
#include <gdk-pixbuf/gdk-pixdata.h>
#include <cairo.h>
+#include <cairo-xlib.h>
+
#include <stdio.h>
#include <stdlib.h>
@@ -198,9 +201,9 @@ init_graphics2d_as_renderable (struct graphics2d *gr)
vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
g_assert (vis != NULL);
- gr->surface = cairo_surface_create_for_drawable (dpy, draw, vis,
- CAIRO_FORMAT_ARGB32,
- DefaultColormap (dpy, DefaultScreen (dpy)));
+ gr->surface = cairo_xlib_surface_create (dpy, draw, vis,
+ CAIRO_FORMAT_ARGB32,
+ DefaultColormap (dpy, DefaultScreen (dpy)));
g_assert (gr->surface != NULL);
g_assert (gr->cr != NULL);
cairo_set_target_surface (gr->cr, gr->surface);
@@ -378,8 +381,8 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
gc = gdk_gc_new (dst->drawable);
g_assert (gc != NULL);
- gdk_draw_drawable(dst->drawable, gc, src->drawable,
- 0, 0, x, y, width, height);
+ gdk_draw_drawable(dst->drawable, gc, src->drawable,
+ 0, 0, x, y, width, height);
g_object_unref (gc);
@@ -474,7 +477,6 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
g_object_unref (gr->drawbuf);
g_object_unref (gr->drawable);
- free (gr);
if (gr->pattern)
cairo_surface_destroy (gr->pattern);
@@ -483,6 +485,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
free (gr->pattern_pixels);
if (gr->debug) printf ("disposed of graphics2d\n");
+ free (gr);
gdk_threads_leave ();
}
@@ -662,6 +665,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
begin_drawing_operation (gr);
+
{
cairo_surface_t *surf = cairo_surface_create_for_image ((char *)jpixels,
CAIRO_FORMAT_ARGB32,
@@ -670,8 +674,9 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
cairo_show_surface (gr->cr, surf, w, h);
cairo_surface_destroy (surf);
}
+
- end_drawing_operation (gr);
+ end_drawing_operation (gr);
(*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
@@ -723,6 +728,82 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
update_pattern_transform (gr);
}
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFont
+ (JNIEnv *env, jobject obj, jobject font)
+{
+ struct graphics2d *gr = NULL;
+ struct peerfont *pfont = NULL;
+ cairo_font_t *ft = NULL;
+ FT_Face face = NULL;
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+
+ gdk_threads_enter ();
+
+ face = pango_ft2_font_get_face (pfont->font);
+ g_assert (face != NULL);
+
+ ft = cairo_ft_font_create_for_ft_face (face);
+ g_assert (ft != NULL);
+
+ if (gr->debug) printf ("cairo_set_font '%s'\n",
+ face->family_name);
+
+ cairo_set_font (gr->cr, ft);
+
+ cairo_scale_font (gr->cr,
+ pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE);
+
+ cairo_font_destroy (ft);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoShowGlyphs
+ (JNIEnv *env, jobject obj, jintArray jcodes, jfloatArray jposns, jint nglyphs)
+{
+ struct graphics2d *gr = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ jfloat *posns = NULL;
+ jint *codes = NULL;
+ jint i;
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ if (gr->debug) printf ("cairo_show_glyphs (%d glyphs)\n", nglyphs);
+
+ glyphs = malloc (sizeof(cairo_glyph_t) * nglyphs);
+ g_assert (glyphs);
+
+ codes = (*env)->GetIntArrayElements (env, jcodes, NULL);
+ g_assert (codes != NULL);
+
+ posns = (*env)->GetFloatArrayElements (env, jposns, NULL);
+ g_assert (posns != NULL);
+
+ for (i = 0; i < nglyphs; ++i)
+ {
+ glyphs[i].index = codes[i];
+ glyphs[i].x = (double) posns[2*i];
+ glyphs[i].y = (double) posns[2*i + 1];
+ }
+
+ (*env)->ReleaseIntArrayElements (env, jcodes, codes, 0);
+ (*env)->ReleaseFloatArrayElements (env, jposns, posns, 0);
+
+ begin_drawing_operation (gr);
+ cairo_show_glyphs (gr->cr, glyphs, nglyphs);
+ end_drawing_operation (gr);
+
+ free(glyphs);
+}
+
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
(JNIEnv *env, jobject obj, jint op)
{