1 /* gnu_java_awt_GdkFont.c
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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.
10
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.
15
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.
20
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.
25
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. */
37
38 #define PANGO_ENABLE_ENGINE
39 #include <pango/pango.h>
40 #include <pango/pangoft2.h>
41 #include <pango/pangofc-font.h>
42 #include <ft2build.h>
43 #include FT_GLYPH_H
44 #include FT_OUTLINE_H
45 #include FT_TYPES_H
46 #include FT_TRUETYPE_TABLES_H
47 #include "gdkfont.h"
48 #include "gtkpeer.h"
49 #include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
50
51 enum java_awt_font_style {
52 java_awt_font_PLAIN = 0,
53 java_awt_font_BOLD = 1,
54 java_awt_font_ITALIC = 2
55 };
56
57 enum java_awt_font_baseline {
58 java_awt_font_ROMAN_BASELINE = 0,
59 java_awt_font_CENTER_BASELINE = 1,
60 java_awt_font_HANGING_BASELINE = 2
61 };
62
63 static PangoFontMap *font_map = NULL;
64
65 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState(JNIEnv * env,jclass clazz)66 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState
67 (JNIEnv *env, jclass clazz __attribute__((unused)))
68 {
69 gtkpeer_init_font_IDs(env);
70 font_map = pango_ft2_font_map_new();
71 }
72
73 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState(JNIEnv * env,jobject self)74 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
75 (JNIEnv *env, jobject self)
76 {
77 struct peerfont *pfont = NULL;
78
79 gdk_threads_enter ();
80
81 g_assert (self != NULL);
82 pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
83 g_assert (pfont != NULL);
84 gtkpeer_set_font (env, self, pfont);
85
86 gdk_threads_leave ();
87 }
88
89
90 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose(JNIEnv * env,jobject self)91 Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
92 (JNIEnv *env, jobject self)
93 {
94 struct peerfont *pfont = NULL;
95
96 gdk_threads_enter ();
97
98 pfont = (struct peerfont *) gtkpeer_get_font (env, self);
99 g_assert (pfont != NULL);
100 if (pfont->layout != NULL)
101 g_object_unref (pfont->layout);
102 if (pfont->font != NULL)
103 g_object_unref (pfont->font);
104 if (pfont->set != NULL)
105 g_object_unref (pfont->set);
106 if (pfont->ctx != NULL)
107 g_object_unref (pfont->ctx);
108 if (pfont->desc != NULL)
109 pango_font_description_free (pfont->desc);
110 g_free (pfont);
111
112 gdk_threads_leave ();
113 }
114
115
116 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_releasePeerGraphicsResource(JNIEnv * env,jobject java_font)117 Java_gnu_java_awt_peer_gtk_GdkFontPeer_releasePeerGraphicsResource
118 (JNIEnv *env, jobject java_font)
119 {
120 struct peerfont *pfont = NULL;
121
122 gdk_threads_enter();
123
124 pfont = (struct peerfont *) gtkpeer_get_font (env, java_font);
125 g_assert (pfont != NULL);
126 if (pfont->graphics_resource != NULL)
127 {
128 cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
129 pfont->graphics_resource = NULL;
130 }
131
132 gdk_threads_leave();
133 }
134
135
136 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics(JNIEnv * env,jobject java_font,jdoubleArray java_metrics)137 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
138 (JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
139 {
140 FT_Face face;
141 struct peerfont *pfont = NULL;
142 jdouble *native_metrics = NULL;
143 short x_ppem;
144 short y_ppem;
145 short units_per_em;
146 double factorx;
147 double factory;
148
149 gdk_threads_enter();
150
151 pfont = (struct peerfont *) gtkpeer_get_font (env, java_font);
152 g_assert (pfont != NULL);
153 face = pango_fc_font_lock_face ((PangoFcFont *)pfont->font);
154
155 native_metrics
156 = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
157
158 g_assert (native_metrics != NULL);
159
160 x_ppem = face->size->metrics.x_ppem;
161 y_ppem = face->size->metrics.y_ppem;
162 units_per_em = face->units_per_EM;
163 factorx = units_per_em / x_ppem;
164 factory = units_per_em / y_ppem;
165 native_metrics[FONT_METRICS_ASCENT] = face->ascender / factory;
166 native_metrics[FONT_METRICS_MAX_ASCENT] = face->bbox.yMax / factory;
167 native_metrics[FONT_METRICS_DESCENT] = - face->descender / factory;
168 native_metrics[FONT_METRICS_MAX_DESCENT] = - face->bbox.yMin / factory;
169 native_metrics[FONT_METRICS_MAX_ADVANCE] = face->max_advance_width / factorx;
170 native_metrics[FONT_METRICS_HEIGHT] = face->height / factory;
171 native_metrics[FONT_METRICS_UNDERLINE_OFFSET] =
172 face->underline_position / factory;
173 native_metrics[FONT_METRICS_UNDERLINE_THICKNESS] =
174 face->underline_thickness / factory;
175
176 pango_fc_font_unlock_face((PangoFcFont *)pfont->font);
177
178 (*env)->ReleaseDoubleArrayElements (env,
179 java_metrics,
180 native_metrics, 0);
181
182 gdk_threads_leave();
183 }
184
185 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics(JNIEnv * env,jobject java_font,jstring str,jdoubleArray java_metrics)186 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
187 (JNIEnv *env, jobject java_font, jstring str, jdoubleArray java_metrics)
188 {
189 struct peerfont *pfont = NULL;
190 const char *cstr = NULL;
191 jdouble *native_metrics = NULL;
192 PangoRectangle log;
193 PangoRectangle log2;
194 int line_count = 0;
195 int i = 0;
196 int width = 0;
197
198 gdk_threads_enter();
199
200 pfont = (struct peerfont *) gtkpeer_get_font(env, java_font);
201 g_assert (pfont != NULL);
202
203 cstr = (*env)->GetStringUTFChars (env, str, NULL);
204 g_assert(cstr != NULL);
205
206 pango_layout_set_text (pfont->layout, cstr, -1);
207 pango_layout_get_extents (pfont->layout, NULL, &log);
208
209 line_count = pango_layout_get_line_count (pfont->layout);
210 for (i = 0; i < line_count; i++)
211 {
212 pango_layout_line_get_extents (pango_layout_get_line (pfont->layout, i),
213 NULL, &log2);
214 width += log2.width;
215 }
216
217 (*env)->ReleaseStringUTFChars (env, str, cstr);
218 pango_layout_set_text (pfont->layout, "", -1);
219
220 native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
221 g_assert (native_metrics != NULL);
222
223 native_metrics[TEXT_METRICS_X_BEARING]
224 = PANGO_PIXELS( ((double)log.x) );
225
226 native_metrics[TEXT_METRICS_Y_BEARING]
227 = PANGO_PIXELS( ((double)log.y) );
228
229 native_metrics[TEXT_METRICS_HEIGHT]
230 = PANGO_PIXELS( ((double)log.height) );
231
232 native_metrics[TEXT_METRICS_WIDTH]
233 = PANGO_PIXELS( ((double)width) );
234
235 native_metrics[TEXT_METRICS_X_ADVANCE]
236 = PANGO_PIXELS( ((double) (log.x + log.width)) );
237
238 native_metrics[TEXT_METRICS_Y_ADVANCE]
239 = PANGO_PIXELS( ((double) (log.y + log.height)) );
240
241 (*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
242
243 gdk_threads_leave();
244 }
245
246
247 JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont(JNIEnv * env,jobject self,jstring family_name_str,jint style_int,jint size)248 Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
249 (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size)
250 {
251 struct peerfont *pfont = NULL;
252 char const *family_name = NULL;
253 enum java_awt_font_style style;
254
255 gdk_threads_enter ();
256
257 style = (enum java_awt_font_style) style_int;
258
259 g_assert (self != NULL);
260 pfont = (struct peerfont *) gtkpeer_get_font(env, self);
261 g_assert (pfont != NULL);
262
263 /* Clear old font information */
264 if (pfont->ctx != NULL)
265 g_object_unref (pfont->ctx);
266 if (pfont->font != NULL)
267 g_object_unref (pfont->font);
268 if (pfont->set != NULL)
269 g_object_unref (pfont->set);
270 if (pfont->desc != NULL)
271 pango_font_description_free (pfont->desc);
272
273 /* Set new description information */
274 pfont->desc = pango_font_description_new ();
275 g_assert (pfont->desc != NULL);
276
277 family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
278 g_assert (family_name != NULL);
279 pango_font_description_set_family (pfont->desc, family_name);
280 (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
281
282 if (style & java_awt_font_BOLD)
283 pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
284
285 if (style & java_awt_font_ITALIC)
286 pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
287
288 pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
289
290 /* Create new context */
291 pfont->ctx = pango_font_map_create_context (font_map);
292 g_assert (pfont->ctx != NULL);
293
294 pango_context_set_font_description (pfont->ctx, pfont->desc);
295 pango_context_set_language (pfont->ctx, gtk_get_default_language());
296
297 /* Create new fontset and default font */
298 pfont->set = pango_context_load_fontset(pfont->ctx, pfont->desc,
299 gtk_get_default_language());
300 pfont->font = pango_context_load_font (pfont->ctx, pfont->desc);
301 g_assert (pfont->font != NULL);
302
303 if (pfont->layout == NULL)
304 pfont->layout = pango_layout_new (pfont->ctx);
305 g_assert (pfont->layout != NULL);
306
307 gdk_threads_leave ();
308 }
309
310
311 JNIEXPORT jbyteArray JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTrueTypeTable(JNIEnv * env,jobject self,jbyte n,jbyte a,jbyte m,jbyte e)312 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTrueTypeTable
313 (JNIEnv *env, jobject self, jbyte n, jbyte a, jbyte m, jbyte e)
314 {
315 struct peerfont *pfont = NULL;
316 FT_Face face;
317 FT_ULong length = 0;
318 FT_ULong tag;
319 int error;
320 FT_Byte *buffer;
321 jbyteArray result_array;
322 jbyte *rbuf;
323
324 pfont = (struct peerfont *) gtkpeer_get_font(env, self);
325 if(pfont == NULL)
326 return NULL;
327
328 gdk_threads_enter ();
329 face = pango_fc_font_lock_face ((PangoFcFont *)pfont->font);
330 tag = FT_MAKE_TAG( n, a, m, e );
331
332 /* Get the length of the table requested */
333 error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );
334 if ( error )
335 {
336 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
337 gdk_threads_leave ();
338 return NULL;
339 }
340
341 buffer = (FT_Byte *)g_malloc0( length );
342 if ( buffer == NULL )
343 {
344 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
345 gdk_threads_leave ();
346 return NULL;
347 }
348 /* get the table data */
349 error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );
350 if ( error )
351 {
352 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
353 g_free(buffer);
354 gdk_threads_leave ();
355 return NULL;
356 }
357
358 /* copy to a jbytearray */
359 result_array = (*env)->NewByteArray (env, length);
360
361 rbuf = (*env)->GetByteArrayElements (env, result_array, NULL);
362 memcpy(rbuf, buffer, length);
363 (*env)->ReleaseByteArrayElements (env, result_array, rbuf, 0);
364
365 g_free(buffer);
366 pango_fc_font_unlock_face ((PangoFcFont *)pfont->font);
367 gdk_threads_leave ();
368
369 /* done */
370 return result_array;
371 }
372