Merge from the pain train
[official-gcc.git] / libjava / jni / gtk-peer / gnu_java_awt_peer_gtk_GdkFontPeer.c
blob7a8a2ceefd89e7ed96d6bfffc1719f838b3da569
1 /* gnu_java_awt_GdkFont.c
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 #include "gdkfont.h"
39 #include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
41 struct state_table *native_font_state_table;
43 enum java_awt_font_style {
44 java_awt_font_PLAIN = 0,
45 java_awt_font_BOLD = 1,
46 java_awt_font_ITALIC = 2
49 enum java_awt_font_baseline {
50 java_awt_font_ROMAN_BASELINE = 0,
51 java_awt_font_CENTER_BASELINE = 1,
52 java_awt_font_HANGING_BASELINE = 2
55 static jmethodID glyphVector_ctor;
56 static jclass glyphVector_class;
57 static PangoAttrList *attrs = NULL;
59 JNIEXPORT void JNICALL
60 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState
61 (JNIEnv *env, jclass clazz)
63 NSA_FONT_INIT (env, clazz);
65 glyphVector_class = (*env)->FindClass
66 (env, "gnu/java/awt/peer/gtk/GdkGlyphVector");
68 glyphVector_ctor = (*env)->GetMethodID
69 (env, glyphVector_class, "<init>",
70 "([D[ILjava/awt/Font;Ljava/awt/font/FontRenderContext;)V");
73 JNIEXPORT void JNICALL
74 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
75 (JNIEnv *env, jobject self)
77 struct peerfont *pfont = NULL;
78 gdk_threads_enter ();
79 g_assert (self != NULL);
80 pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
81 g_assert (pfont != NULL);
82 NSA_SET_FONT_PTR (env, self, pfont);
83 gdk_threads_leave ();
87 JNIEXPORT void JNICALL
88 Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
89 (JNIEnv *env, jobject self)
91 struct peerfont *pfont = NULL;
93 gdk_threads_enter ();
94 pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self);
95 g_assert (pfont != NULL);
96 if (pfont->layout != NULL)
97 g_object_unref (pfont->font);
98 if (pfont->font != NULL)
99 g_object_unref (pfont->font);
100 if (pfont->ctx != NULL)
101 g_object_unref (pfont->ctx);
102 if (pfont->desc != NULL)
103 pango_font_description_free (pfont->desc);
104 g_free (pfont);
105 gdk_threads_leave ();
109 JNIEXPORT jobject JNICALL
110 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
111 (JNIEnv *env, jobject self,
112 jstring chars,
113 jobject font,
114 jobject fontRenderContext)
116 struct peerfont *pfont = NULL;
117 GList *items = NULL, *i = NULL;
118 gchar *str = NULL;
119 int len, j;
120 double *native_extents;
121 int *native_codes;
122 jintArray java_codes = NULL;
123 jdoubleArray java_extents = NULL;
125 gdk_threads_enter ();
127 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
128 g_assert (pfont != NULL);
130 len = (*gdk_env())->GetStringUTFLength (env, chars);
131 str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
132 g_assert (str != NULL);
134 if (attrs == NULL)
135 attrs = pango_attr_list_new ();
137 if (len > 0 && str[len-1] == '\0')
138 len--;
140 items = pango_itemize (pfont->ctx, str, 0, len, attrs, NULL);
142 i = g_list_first (items);
144 if (i == NULL)
146 java_extents = (*env)->NewDoubleArray (env, 0);
147 java_codes = (*env)->NewIntArray (env, 0);
149 else
151 PangoGlyphString *glyphs;
152 PangoItem *item = (PangoItem *)i->data;
154 pango_context_set_font_description (pfont->ctx, pfont->desc);
155 pango_context_set_language (pfont->ctx, gtk_get_default_language());
156 pango_context_load_font (pfont->ctx, pfont->desc);
158 glyphs = pango_glyph_string_new ();
159 g_assert (glyphs != NULL);
161 pango_shape (str + item->offset, item->length,
162 &(item->analysis), glyphs);
164 if (glyphs->num_glyphs > 0)
166 int x = 0;
167 double scale = ((double) PANGO_SCALE);
169 java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS);
170 java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs);
171 native_extents = (*env)->GetDoubleArrayElements (env, java_extents, NULL);
172 native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
174 for (j = 0; j < glyphs->num_glyphs; ++j)
176 PangoRectangle ink;
177 PangoRectangle logical;
178 PangoGlyphGeometry *geom = &glyphs->glyphs[j].geometry;
180 pango_font_get_glyph_extents (pfont->font,
181 glyphs->glyphs[j].glyph,
182 &ink, &logical);
184 native_codes[j] = glyphs->glyphs[j].glyph;
186 native_extents[ GLYPH_LOG_X(j) ] = (logical.x) / scale;
187 native_extents[ GLYPH_LOG_Y(j) ] = (- logical.y) / scale;
188 native_extents[ GLYPH_LOG_WIDTH(j) ] = (logical.width) / scale;
189 native_extents[ GLYPH_LOG_HEIGHT(j) ] = (logical.height) / scale;
191 native_extents[ GLYPH_INK_X(j) ] = (ink.x) / scale;
192 native_extents[ GLYPH_INK_Y(j) ] = (- ink.y) / scale;
193 native_extents[ GLYPH_INK_WIDTH(j) ] = (ink.width) / scale;
194 native_extents[ GLYPH_INK_HEIGHT(j) ] = (ink.height) / scale;
196 native_extents[ GLYPH_POS_X(j) ] = (x + geom->x_offset) / scale;
197 native_extents[ GLYPH_POS_Y(j) ] = ( - geom->y_offset) / scale;
199 x += geom->width;
201 (*env)->ReleaseDoubleArrayElements (env, java_extents, native_extents, 0);
202 (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
205 pango_glyph_string_free (glyphs);
208 (*env)->ReleaseStringUTFChars (env, chars, str);
210 for (i = g_list_first (items); i != NULL; i = g_list_next (i))
211 g_free (i->data);
213 g_list_free (items);
215 gdk_threads_leave ();
217 return (*env)->NewObject (env,
218 glyphVector_class,
219 glyphVector_ctor,
220 java_extents, java_codes,
221 font, fontRenderContext);
224 JNIEXPORT void JNICALL
225 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
226 (JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
228 struct peerfont *pfont = NULL;
229 jdouble *native_metrics = NULL;
230 PangoFontMetrics *pango_metrics;
232 gdk_threads_enter();
234 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
235 g_assert (pfont != NULL);
237 pango_metrics
238 = pango_context_get_metrics (pfont->ctx, pfont->desc,
239 gtk_get_default_language ());
241 native_metrics
242 = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
244 g_assert (native_metrics != NULL);
246 native_metrics[FONT_METRICS_ASCENT]
247 = PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics));
249 native_metrics[FONT_METRICS_MAX_ASCENT]
250 = native_metrics[FONT_METRICS_ASCENT];
252 native_metrics[FONT_METRICS_DESCENT]
253 = PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics));
255 if (native_metrics[FONT_METRICS_DESCENT] < 0)
256 native_metrics[FONT_METRICS_DESCENT]
257 = - native_metrics[FONT_METRICS_DESCENT];
259 native_metrics[FONT_METRICS_MAX_DESCENT]
260 = native_metrics[FONT_METRICS_DESCENT];
262 native_metrics[FONT_METRICS_MAX_ADVANCE]
263 = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width
264 (pango_metrics));
266 (*env)->ReleaseDoubleArrayElements (env,
267 java_metrics,
268 native_metrics, 0);
270 pango_font_metrics_unref (pango_metrics);
272 gdk_threads_leave();
275 JNIEXPORT void JNICALL
276 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
277 (JNIEnv *env, jobject java_font, jstring str, jdoubleArray java_metrics)
279 struct peerfont *pfont = NULL;
280 const char *cstr = NULL;
281 jdouble *native_metrics = NULL;
282 PangoRectangle log;
284 gdk_threads_enter();
286 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font);
287 g_assert (pfont != NULL);
289 cstr = (*env)->GetStringUTFChars (env, str, NULL);
290 g_assert(cstr != NULL);
292 pango_layout_set_text (pfont->layout, cstr, -1);
293 pango_layout_get_extents (pfont->layout, NULL, &log);
295 (*env)->ReleaseStringUTFChars (env, str, cstr);
296 pango_layout_set_text (pfont->layout, "", -1);
298 native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
299 g_assert (native_metrics != NULL);
301 native_metrics[TEXT_METRICS_X_BEARING]
302 = PANGO_PIXELS( ((double)log.x) );
304 native_metrics[TEXT_METRICS_Y_BEARING]
305 = PANGO_PIXELS( ((double)log.y) );
307 native_metrics[TEXT_METRICS_WIDTH]
308 = PANGO_PIXELS( ((double)log.width) );
310 native_metrics[TEXT_METRICS_HEIGHT]
311 = PANGO_PIXELS( ((double)log.height) );
313 native_metrics[TEXT_METRICS_X_ADVANCE]
314 = PANGO_PIXELS( ((double) (log.x + log.width)) );
316 native_metrics[TEXT_METRICS_Y_ADVANCE]
317 = PANGO_PIXELS( ((double) (log.y + log.height)) );
319 (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
321 gdk_threads_leave();
325 JNIEXPORT void JNICALL
326 Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
327 (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D)
329 struct peerfont *pfont = NULL;
330 char const *family_name = NULL;
331 enum java_awt_font_style style;
332 PangoFT2FontMap *ft2_map;
334 gdk_threads_enter ();
335 style = (enum java_awt_font_style) style_int;
337 g_assert (self != NULL);
338 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
339 g_assert (pfont != NULL);
341 if (pfont->ctx != NULL)
342 g_object_unref (pfont->ctx);
343 if (pfont->font != NULL)
344 g_object_unref (pfont->font);
345 if (pfont->desc != NULL)
346 pango_font_description_free (pfont->desc);
348 pfont->desc = pango_font_description_new ();
349 g_assert (pfont->desc != NULL);
351 family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
352 g_assert (family_name != NULL);
353 pango_font_description_set_family (pfont->desc, family_name);
354 (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
357 if (style & java_awt_font_BOLD)
358 pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
360 if (style & java_awt_font_ITALIC)
361 pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
363 if (useGraphics2D)
365 pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
366 if (pfont->ctx == NULL)
368 ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
369 pfont->ctx = pango_ft2_font_map_create_context (ft2_map);
372 else
374 /* GDK uses a slightly different DPI setting. */
375 pango_font_description_set_size (pfont->desc,
376 size * dpi_conversion_factor);
377 if (pfont->ctx == NULL)
378 pfont->ctx = gdk_pango_context_get();
381 g_assert (pfont->ctx != NULL);
383 if (pfont->font != NULL)
385 g_object_unref (pfont->font);
386 pfont->font = NULL;
389 pango_context_set_font_description (pfont->ctx, pfont->desc);
390 pango_context_set_language (pfont->ctx, gtk_get_default_language());
391 pfont->font = pango_context_load_font (pfont->ctx, pfont->desc);
392 g_assert (pfont->font != NULL);
394 if (pfont->layout == NULL)
395 pfont->layout = pango_layout_new (pfont->ctx);
396 g_assert (pfont->layout != NULL);
398 gdk_threads_leave ();