Import GNU Classpath (20121202).
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GdkFontPeer.c
blob771b23e3738aa1d745d2ad3bafbab722963ee5f1
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 #define PANGO_ENABLE_ENGINE
39 #include <pango/pango.h>
40 #include <pango/pangoft2.h>
41 #include <pango/pangofc-font.h>
42 #include <freetype/ftglyph.h>
43 #include <freetype/ftoutln.h>
44 #include <freetype/fttypes.h>
45 #include <freetype/tttables.h>
46 #include "gdkfont.h"
47 #include "gtkpeer.h"
48 #include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
50 enum java_awt_font_style {
51 java_awt_font_PLAIN = 0,
52 java_awt_font_BOLD = 1,
53 java_awt_font_ITALIC = 2
56 enum java_awt_font_baseline {
57 java_awt_font_ROMAN_BASELINE = 0,
58 java_awt_font_CENTER_BASELINE = 1,
59 java_awt_font_HANGING_BASELINE = 2
62 static PangoFontMap *font_map = NULL;
64 JNIEXPORT void JNICALL
65 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState
66 (JNIEnv *env, jclass clazz __attribute__((unused)))
68 gtkpeer_init_font_IDs(env);
69 font_map = pango_ft2_font_map_new();
72 JNIEXPORT void JNICALL
73 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
74 (JNIEnv *env, jobject self)
76 struct peerfont *pfont = NULL;
78 gdk_threads_enter ();
80 g_assert (self != NULL);
81 pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
82 g_assert (pfont != NULL);
83 gtkpeer_set_font (env, self, pfont);
85 gdk_threads_leave ();
89 JNIEXPORT void JNICALL
90 Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
91 (JNIEnv *env, jobject self)
93 struct peerfont *pfont = NULL;
95 gdk_threads_enter ();
97 pfont = (struct peerfont *) gtkpeer_get_font (env, self);
98 g_assert (pfont != NULL);
99 if (pfont->layout != NULL)
100 g_object_unref (pfont->layout);
101 if (pfont->font != NULL)
102 g_object_unref (pfont->font);
103 if (pfont->set != NULL)
104 g_object_unref (pfont->set);
105 if (pfont->ctx != NULL)
106 g_object_unref (pfont->ctx);
107 if (pfont->desc != NULL)
108 pango_font_description_free (pfont->desc);
109 g_free (pfont);
111 gdk_threads_leave ();
115 JNIEXPORT void JNICALL
116 Java_gnu_java_awt_peer_gtk_GdkFontPeer_releasePeerGraphicsResource
117 (JNIEnv *env, jobject java_font)
119 struct peerfont *pfont = NULL;
121 gdk_threads_enter();
123 pfont = (struct peerfont *) gtkpeer_get_font (env, java_font);
124 g_assert (pfont != NULL);
125 if (pfont->graphics_resource != NULL)
127 cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
128 pfont->graphics_resource = NULL;
131 gdk_threads_leave();
135 JNIEXPORT void JNICALL
136 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
137 (JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
139 FT_Face face;
140 struct peerfont *pfont = NULL;
141 jdouble *native_metrics = NULL;
142 short x_ppem;
143 short y_ppem;
144 short units_per_em;
145 double factorx;
146 double factory;
148 gdk_threads_enter();
150 pfont = (struct peerfont *) gtkpeer_get_font (env, java_font);
151 g_assert (pfont != NULL);
152 face = pango_fc_font_lock_face ((PangoFcFont *)pfont->font);
154 native_metrics
155 = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
157 g_assert (native_metrics != NULL);
159 x_ppem = face->size->metrics.x_ppem;
160 y_ppem = face->size->metrics.y_ppem;
161 units_per_em = face->units_per_EM;
162 factorx = units_per_em / x_ppem;
163 factory = units_per_em / y_ppem;
164 native_metrics[FONT_METRICS_ASCENT] = face->ascender / factory;
165 native_metrics[FONT_METRICS_MAX_ASCENT] = face->bbox.yMax / factory;
166 native_metrics[FONT_METRICS_DESCENT] = - face->descender / factory;
167 native_metrics[FONT_METRICS_MAX_DESCENT] = - face->bbox.yMin / factory;
168 native_metrics[FONT_METRICS_MAX_ADVANCE] = face->max_advance_width / factorx;
169 native_metrics[FONT_METRICS_HEIGHT] = face->height / factory;
170 native_metrics[FONT_METRICS_UNDERLINE_OFFSET] =
171 face->underline_position / factory;
172 native_metrics[FONT_METRICS_UNDERLINE_THICKNESS] =
173 face->underline_thickness / factory;
175 pango_fc_font_unlock_face((PangoFcFont *)pfont->font);
177 (*env)->ReleaseDoubleArrayElements (env,
178 java_metrics,
179 native_metrics, 0);
181 gdk_threads_leave();
184 JNIEXPORT void JNICALL
185 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
186 (JNIEnv *env, jobject java_font, jstring str, jdoubleArray java_metrics)
188 struct peerfont *pfont = NULL;
189 const char *cstr = NULL;
190 jdouble *native_metrics = NULL;
191 PangoRectangle log;
192 PangoRectangle log2;
193 int line_count = 0;
194 int i = 0;
195 int width = 0;
197 gdk_threads_enter();
199 pfont = (struct peerfont *) gtkpeer_get_font(env, java_font);
200 g_assert (pfont != NULL);
202 cstr = (*env)->GetStringUTFChars (env, str, NULL);
203 g_assert(cstr != NULL);
205 pango_layout_set_text (pfont->layout, cstr, -1);
206 pango_layout_get_extents (pfont->layout, NULL, &log);
208 line_count = pango_layout_get_line_count (pfont->layout);
209 for (i = 0; i < line_count; i++)
211 pango_layout_line_get_extents (pango_layout_get_line (pfont->layout, i),
212 NULL, &log2);
213 width += log2.width;
216 (*env)->ReleaseStringUTFChars (env, str, cstr);
217 pango_layout_set_text (pfont->layout, "", -1);
219 native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
220 g_assert (native_metrics != NULL);
222 native_metrics[TEXT_METRICS_X_BEARING]
223 = PANGO_PIXELS( ((double)log.x) );
225 native_metrics[TEXT_METRICS_Y_BEARING]
226 = PANGO_PIXELS( ((double)log.y) );
228 native_metrics[TEXT_METRICS_HEIGHT]
229 = PANGO_PIXELS( ((double)log.height) );
231 native_metrics[TEXT_METRICS_WIDTH]
232 = PANGO_PIXELS( ((double)width) );
234 native_metrics[TEXT_METRICS_X_ADVANCE]
235 = PANGO_PIXELS( ((double) (log.x + log.width)) );
237 native_metrics[TEXT_METRICS_Y_ADVANCE]
238 = PANGO_PIXELS( ((double) (log.y + log.height)) );
240 (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
242 gdk_threads_leave();
246 JNIEXPORT void JNICALL
247 Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
248 (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size)
250 struct peerfont *pfont = NULL;
251 char const *family_name = NULL;
252 enum java_awt_font_style style;
254 gdk_threads_enter ();
256 style = (enum java_awt_font_style) style_int;
258 g_assert (self != NULL);
259 pfont = (struct peerfont *) gtkpeer_get_font(env, self);
260 g_assert (pfont != NULL);
262 /* Clear old font information */
263 if (pfont->ctx != NULL)
264 g_object_unref (pfont->ctx);
265 if (pfont->font != NULL)
266 g_object_unref (pfont->font);
267 if (pfont->set != NULL)
268 g_object_unref (pfont->set);
269 if (pfont->desc != NULL)
270 pango_font_description_free (pfont->desc);
272 /* Set new description information */
273 pfont->desc = pango_font_description_new ();
274 g_assert (pfont->desc != NULL);
276 family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
277 g_assert (family_name != NULL);
278 pango_font_description_set_family (pfont->desc, family_name);
279 (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
281 if (style & java_awt_font_BOLD)
282 pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
284 if (style & java_awt_font_ITALIC)
285 pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
287 pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
289 /* Create new context */
290 pfont->ctx = pango_font_map_create_context (font_map);
291 g_assert (pfont->ctx != NULL);
293 pango_context_set_font_description (pfont->ctx, pfont->desc);
294 pango_context_set_language (pfont->ctx, gtk_get_default_language());
296 /* Create new fontset and default font */
297 pfont->set = pango_context_load_fontset(pfont->ctx, pfont->desc,
298 gtk_get_default_language());
299 pfont->font = pango_context_load_font (pfont->ctx, pfont->desc);
300 g_assert (pfont->font != NULL);
302 if (pfont->layout == NULL)
303 pfont->layout = pango_layout_new (pfont->ctx);
304 g_assert (pfont->layout != NULL);
306 gdk_threads_leave ();
310 JNIEXPORT jbyteArray JNICALL
311 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTrueTypeTable
312 (JNIEnv *env, jobject self, jbyte n, jbyte a, jbyte m, jbyte e)
314 struct peerfont *pfont = NULL;
315 FT_Face face;
316 FT_ULong length = 0;
317 FT_ULong tag;
318 int error;
319 FT_Byte *buffer;
320 jbyteArray result_array;
321 jbyte *rbuf;
323 pfont = (struct peerfont *) gtkpeer_get_font(env, self);
324 if(pfont == NULL)
325 return NULL;
327 gdk_threads_enter ();
328 face = pango_fc_font_lock_face ((PangoFcFont *)pfont->font);
329 tag = FT_MAKE_TAG( n, a, m, e );
331 /* Get the length of the table requested */
332 error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );
333 if ( error )
335 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
336 gdk_threads_leave ();
337 return NULL;
340 buffer = (FT_Byte *)g_malloc0( length );
341 if ( buffer == NULL )
343 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
344 gdk_threads_leave ();
345 return NULL;
347 /* get the table data */
348 error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );
349 if ( error )
351 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
352 g_free(buffer);
353 gdk_threads_leave ();
354 return NULL;
357 /* copy to a jbytearray */
358 result_array = (*env)->NewByteArray (env, length);
360 rbuf = (*env)->GetByteArrayElements (env, result_array, NULL);
361 memcpy(rbuf, buffer, length);
362 (*env)->ReleaseByteArrayElements (env, result_array, rbuf, 0);
364 g_free(buffer);
365 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
366 gdk_threads_leave ();
368 /* done */
369 return result_array;