Merge from mainline
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GdkFontPeer.c
blob30f2d5e24cd8233b7696815ee44783f9ff42704d
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 *cp_gtk_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_class = (*env)->NewGlobalRef
69 (env, glyphVector_class);
71 glyphVector_ctor = (*env)->GetMethodID
72 (env, glyphVector_class, "<init>",
73 "([D[ILjava/awt/Font;Ljava/awt/font/FontRenderContext;)V");
76 JNIEXPORT void JNICALL
77 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
78 (JNIEnv *env, jobject self)
80 struct peerfont *pfont = NULL;
82 gdk_threads_enter ();
84 g_assert (self != NULL);
85 pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
86 g_assert (pfont != NULL);
87 NSA_SET_FONT_PTR (env, self, pfont);
89 gdk_threads_leave ();
93 JNIEXPORT void JNICALL
94 Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
95 (JNIEnv *env, jobject self)
97 struct peerfont *pfont = NULL;
99 gdk_threads_enter ();
101 pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self);
102 g_assert (pfont != NULL);
103 if (pfont->layout != NULL)
104 g_object_unref (pfont->layout);
105 if (pfont->font != NULL)
106 g_object_unref (pfont->font);
107 if (pfont->ctx != NULL)
108 g_object_unref (pfont->ctx);
109 if (pfont->desc != NULL)
110 pango_font_description_free (pfont->desc);
111 g_free (pfont);
113 gdk_threads_leave ();
117 JNIEXPORT jobject JNICALL
118 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
119 (JNIEnv *env, jobject self,
120 jstring chars,
121 jobject font,
122 jobject fontRenderContext)
124 struct peerfont *pfont = NULL;
125 GList *items = NULL;
126 GList *i = NULL;
127 gchar *str = NULL;
128 int len = 0;
129 int j = 0;
130 double *native_extents = NULL;
131 int *native_codes = NULL;
132 jintArray java_codes = NULL;
133 jdoubleArray java_extents = NULL;
135 gdk_threads_enter ();
137 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
138 g_assert (pfont != NULL);
140 len = (*cp_gtk_gdk_env())->GetStringUTFLength (env, chars);
141 str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
142 g_assert (str != NULL);
144 if (attrs == NULL)
145 attrs = pango_attr_list_new ();
147 if (len > 0 && str[len-1] == '\0')
148 len--;
150 items = pango_itemize (pfont->ctx, str, 0, len, attrs, NULL);
152 i = g_list_first (items);
154 if (i == NULL)
156 java_extents = (*env)->NewDoubleArray (env, 0);
157 java_codes = (*env)->NewIntArray (env, 0);
159 else
161 PangoGlyphString *glyphs;
162 PangoItem *item = (PangoItem *)i->data;
164 pango_context_set_font_description (pfont->ctx, pfont->desc);
165 pango_context_set_language (pfont->ctx, gtk_get_default_language());
166 pango_context_load_font (pfont->ctx, pfont->desc);
168 glyphs = pango_glyph_string_new ();
169 g_assert (glyphs != NULL);
171 pango_shape (str + item->offset, item->length,
172 &(item->analysis), glyphs);
174 if (glyphs->num_glyphs > 0)
176 int x = 0;
177 double scale = ((double) PANGO_SCALE);
179 java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS);
180 java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs);
182 native_extents = (*env)->GetDoubleArrayElements (env, java_extents, NULL);
183 native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
185 for (j = 0; j < glyphs->num_glyphs; ++j)
187 PangoRectangle ink;
188 PangoRectangle logical;
189 PangoGlyphGeometry *geom = &glyphs->glyphs[j].geometry;
191 pango_font_get_glyph_extents (pfont->font,
192 glyphs->glyphs[j].glyph,
193 &ink, &logical);
195 native_codes[j] = glyphs->glyphs[j].glyph;
197 native_extents[ GLYPH_LOG_X(j) ] = (logical.x) / scale;
198 native_extents[ GLYPH_LOG_Y(j) ] = (- logical.y) / scale;
199 native_extents[ GLYPH_LOG_WIDTH(j) ] = (logical.width) / scale;
200 native_extents[ GLYPH_LOG_HEIGHT(j) ] = (logical.height) / scale;
202 native_extents[ GLYPH_INK_X(j) ] = (ink.x) / scale;
203 native_extents[ GLYPH_INK_Y(j) ] = (- ink.y) / scale;
204 native_extents[ GLYPH_INK_WIDTH(j) ] = (ink.width) / scale;
205 native_extents[ GLYPH_INK_HEIGHT(j) ] = (ink.height) / scale;
207 native_extents[ GLYPH_POS_X(j) ] = (x + geom->x_offset) / scale;
208 native_extents[ GLYPH_POS_Y(j) ] = ( - geom->y_offset) / scale;
210 x += geom->width;
212 (*env)->ReleaseDoubleArrayElements (env, java_extents, native_extents, 0);
213 (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
216 pango_glyph_string_free (glyphs);
219 (*env)->ReleaseStringUTFChars (env, chars, str);
221 for (i = g_list_first (items); i != NULL; i = g_list_next (i))
222 g_free (i->data);
224 g_list_free (items);
226 gdk_threads_leave ();
228 return (*env)->NewObject (env,
229 glyphVector_class,
230 glyphVector_ctor,
231 java_extents, java_codes,
232 font, fontRenderContext);
235 JNIEXPORT void JNICALL
236 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
237 (JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
239 struct peerfont *pfont = NULL;
240 jdouble *native_metrics = NULL;
241 PangoFontMetrics *pango_metrics = NULL;
243 gdk_threads_enter();
245 pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
246 g_assert (pfont != NULL);
248 pango_metrics
249 = pango_context_get_metrics (pfont->ctx, pfont->desc,
250 gtk_get_default_language ());
252 native_metrics
253 = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
255 g_assert (native_metrics != NULL);
257 native_metrics[FONT_METRICS_ASCENT]
258 = PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics));
260 native_metrics[FONT_METRICS_MAX_ASCENT]
261 = native_metrics[FONT_METRICS_ASCENT];
263 native_metrics[FONT_METRICS_DESCENT]
264 = PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics));
266 if (native_metrics[FONT_METRICS_DESCENT] < 0)
267 native_metrics[FONT_METRICS_DESCENT]
268 = - native_metrics[FONT_METRICS_DESCENT];
270 native_metrics[FONT_METRICS_MAX_DESCENT]
271 = native_metrics[FONT_METRICS_DESCENT];
273 native_metrics[FONT_METRICS_MAX_ADVANCE]
274 = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width
275 (pango_metrics));
277 (*env)->ReleaseDoubleArrayElements (env,
278 java_metrics,
279 native_metrics, 0);
281 pango_font_metrics_unref (pango_metrics);
283 gdk_threads_leave();
286 JNIEXPORT void JNICALL
287 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
288 (JNIEnv *env, jobject java_font, jstring str, jdoubleArray java_metrics)
290 struct peerfont *pfont = NULL;
291 const char *cstr = NULL;
292 jdouble *native_metrics = NULL;
293 PangoRectangle log;
294 PangoRectangle log2;
295 int line_count = 0;
296 int i = 0;
297 int width = 0;
299 gdk_threads_enter();
301 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font);
302 g_assert (pfont != NULL);
304 cstr = (*env)->GetStringUTFChars (env, str, NULL);
305 g_assert(cstr != NULL);
307 pango_layout_set_text (pfont->layout, cstr, -1);
308 pango_layout_get_extents (pfont->layout, NULL, &log);
310 line_count = pango_layout_get_line_count (pfont->layout);
311 for (i = 0; i < line_count; i++)
313 pango_layout_line_get_extents (pango_layout_get_line (pfont->layout, i),
314 NULL, &log2);
315 width += log2.width;
318 (*env)->ReleaseStringUTFChars (env, str, cstr);
319 pango_layout_set_text (pfont->layout, "", -1);
321 native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
322 g_assert (native_metrics != NULL);
324 native_metrics[TEXT_METRICS_X_BEARING]
325 = PANGO_PIXELS( ((double)log.x) );
327 native_metrics[TEXT_METRICS_Y_BEARING]
328 = PANGO_PIXELS( ((double)log.y) );
330 native_metrics[TEXT_METRICS_HEIGHT]
331 = PANGO_PIXELS( ((double)log.height) );
333 native_metrics[TEXT_METRICS_WIDTH]
334 = PANGO_PIXELS( ((double)width) );
336 native_metrics[TEXT_METRICS_X_ADVANCE]
337 = PANGO_PIXELS( ((double) (log.x + log.width)) );
339 native_metrics[TEXT_METRICS_Y_ADVANCE]
340 = PANGO_PIXELS( ((double) (log.y + log.height)) );
342 (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
344 gdk_threads_leave();
348 JNIEXPORT void JNICALL
349 Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
350 (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D)
352 struct peerfont *pfont = NULL;
353 char const *family_name = NULL;
354 enum java_awt_font_style style;
355 PangoFT2FontMap *ft2_map = NULL;
357 gdk_threads_enter ();
359 style = (enum java_awt_font_style) style_int;
361 g_assert (self != NULL);
362 pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
363 g_assert (pfont != NULL);
365 if (pfont->ctx != NULL)
366 g_object_unref (pfont->ctx);
367 if (pfont->font != NULL)
368 g_object_unref (pfont->font);
369 if (pfont->desc != NULL)
370 pango_font_description_free (pfont->desc);
372 pfont->desc = pango_font_description_new ();
373 g_assert (pfont->desc != NULL);
375 family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
376 g_assert (family_name != NULL);
377 pango_font_description_set_family (pfont->desc, family_name);
378 (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
381 if (style & java_awt_font_BOLD)
382 pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
384 if (style & java_awt_font_ITALIC)
385 pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
387 if (useGraphics2D)
389 pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
390 if (pfont->ctx == NULL)
392 ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
393 pfont->ctx = pango_ft2_font_map_create_context (ft2_map);
396 else
398 /* GDK uses a slightly different DPI setting. */
399 pango_font_description_set_size (pfont->desc,
400 size * cp_gtk_dpi_conversion_factor);
401 if (pfont->ctx == NULL)
402 pfont->ctx = gdk_pango_context_get();
405 g_assert (pfont->ctx != NULL);
407 if (pfont->font != NULL)
409 g_object_unref (pfont->font);
410 pfont->font = NULL;
413 pango_context_set_font_description (pfont->ctx, pfont->desc);
414 pango_context_set_language (pfont->ctx, gtk_get_default_language());
415 pfont->font = pango_context_load_font (pfont->ctx, pfont->desc);
416 g_assert (pfont->font != NULL);
418 if (pfont->layout == NULL)
419 pfont->layout = pango_layout_new (pfont->ctx);
420 g_assert (pfont->layout != NULL);
422 gdk_threads_leave ();