Reverting merge from trunk
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_FreetypeGlyphVector.c
blobcb7bf43dcb46de6528fb5318c1333f2850766f0b
1 /* gnu_java_awt_FreetypeGlyphVector.c
2 Copyright (C) 2006 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 <jni.h>
40 #include <gtk/gtk.h>
41 #include <string.h>
42 #include <pango/pango.h>
43 #include <pango/pangoft2.h>
44 #include <pango/pangofc-font.h>
45 #include <freetype/ftglyph.h>
46 #include <freetype/ftoutln.h>
47 #include "jcl.h"
48 #include "gdkfont.h"
49 #include "gnu_java_awt_peer_gtk_FreetypeGlyphVector.h"
50 #include "cairographics2d.h"
52 typedef struct gp
54 JNIEnv *env;
55 jobject obj;
56 double px;
57 double py;
58 double sx;
59 double sy;
60 } generalpath ;
62 static PangoFcFont *
63 getFont(JNIEnv *env, jobject obj)
65 jfieldID fid;
66 jobject data;
67 jclass cls;
68 struct peerfont *pfont;
70 cls = (*env)->GetObjectClass (env, obj);
71 fid = (*env)->GetFieldID (env, cls, "peer",
72 "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
73 g_assert (fid != 0);
75 data = (*env)->GetObjectField (env, obj, fid);
76 g_assert (data != NULL);
78 pfont = (struct peerfont *) gtkpeer_get_font(env, data);
79 g_assert (pfont != NULL);
80 g_assert (pfont->font != NULL);
82 return (PangoFcFont *)pfont->font;
85 static PangoFontset *
86 getFontSet(JNIEnv *env, jobject obj)
88 jfieldID fid;
89 jobject data;
90 jclass cls;
91 struct peerfont *pfont;
93 cls = (*env)->GetObjectClass (env, obj);
94 fid = (*env)->GetFieldID (env, cls, "peer",
95 "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
96 g_assert (fid != 0);
98 data = (*env)->GetObjectField (env, obj, fid);
99 g_assert (data != NULL);
101 pfont = (struct peerfont *) gtkpeer_get_font (env, data);
102 g_assert (pfont != NULL);
103 g_assert (pfont->font != NULL);
105 return (PangoFontset *)pfont->set;
108 JNIEXPORT void JNICALL
109 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphs
110 (JNIEnv *env, jobject obj, jintArray codepoints, jintArray glyphs,
111 jlongArray fonts)
113 PangoFcFont *default_font, *current_font;
114 PangoFontset *pfs;
115 jint *cpvals;
116 jint length;
117 int i;
119 /* Set up default font and fontset */
120 default_font = getFont(env, obj);
121 current_font = default_font;
122 pfs = getFontSet(env, obj);
124 /* Retrieve string information */
125 length = (*env)->GetArrayLength (env, codepoints);
126 cpvals = (*env)->GetIntArrayElements (env, codepoints, NULL);
128 jint *glyphArray = (*env)->GetIntArrayElements (env, glyphs, NULL);
129 jlong *fontArray = (*env)->GetLongArrayElements (env, fonts, NULL);
131 /* A design goal of Pango is to be threadsafe, but it's admitted that it is
132 * not actually threadsafe at the moment. Using gdk locking here to be safe,
133 * but I don't know if if actually helps at all... */
134 gdk_threads_enter();
136 for( i = 0; i < length; i++ )
138 /* Ensure the current font has the requested character; if it doesn't,
139 * try the default font before pulling a new font out of the fontset.
140 * Once chosen, a font will be used until a character not in the font is
141 * encountered. */
142 if (!pango_fc_font_has_char(current_font, cpvals[i]))
144 if (pango_fc_font_has_char(default_font, cpvals[i]))
146 current_font = default_font;
147 g_object_ref(current_font);
149 else
151 current_font = (PangoFcFont*)pango_fontset_get_font(pfs, cpvals[i]);
154 else
156 g_object_ref(current_font);
159 /* Get glyph, and store both glyph and pointer to font */
160 glyphArray[i] = (int)pango_fc_font_get_glyph(current_font,
161 (gunichar)cpvals[i]);
162 fontArray[i] = PTR_TO_JLONG(current_font);
165 gdk_threads_leave();
167 (*env)->ReleaseIntArrayElements (env, glyphs, glyphArray, 0);
168 (*env)->ReleaseIntArrayElements (env, codepoints, cpvals, 0);
169 (*env)->ReleaseLongArrayElements (env, fonts, fontArray, 0);
172 JNIEXPORT void JNICALL
173 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getKerning
174 (JNIEnv *env, jobject obj __attribute__((unused)), jint rightGlyph,
175 jint leftGlyph, jlong fnt, jfloatArray p)
177 FT_Face ft_face;
178 FT_Vector kern;
179 PangoFcFont *font;
181 font = JLONG_TO_PTR(PangoFcFont, fnt);
182 ft_face = pango_fc_font_lock_face( font );
183 g_assert (ft_face != NULL);
184 FT_Get_Kerning( ft_face, rightGlyph, leftGlyph, FT_KERNING_DEFAULT, &kern );
186 pango_fc_font_unlock_face( font );
188 jfloat *pelements = (*env)->GetPrimitiveArrayCritical(env, p, NULL);
189 pelements[0] = (jfloat)kern.x/64.0;
190 pelements[1] = (jfloat)kern.y/64.0;
191 (*env)->ReleasePrimitiveArrayCritical (env, p, pelements, 0);
194 JNIEXPORT jdoubleArray JNICALL
195 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative
196 (JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
198 FT_Face ft_face;
199 jdouble *values;
200 jdoubleArray retArray = NULL;
201 PangoFcFont *font;
203 font = JLONG_TO_PTR(PangoFcFont, fnt);
204 ft_face = pango_fc_font_lock_face( font );
206 g_assert (ft_face != NULL);
208 FT_Set_Transform( ft_face, NULL, NULL );
210 if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_NO_BITMAP ) != 0 )
212 pango_fc_font_unlock_face( font );
213 printf("Couldn't load glyph %i\n", glyphIndex);
214 return NULL;
217 retArray = (*env)->NewDoubleArray (env, 8);
218 values = (*env)->GetDoubleArrayElements (env, retArray, NULL);
220 values[0] = 0;
221 values[1] = (jdouble)ft_face->glyph->advance.x/64.0;
222 values[2] = (jdouble)ft_face->glyph->advance.y/64.0;
223 values[3] = (jdouble)ft_face->glyph->metrics.horiBearingX/64.0;
224 values[4] = -(jdouble)ft_face->glyph->metrics.horiBearingY/64.0;
225 values[5] = (jdouble)ft_face->glyph->metrics.width/64.0;
226 values[6] = (jdouble)ft_face->glyph->metrics.height/64.0;
227 values[7] = 0;
229 (*env)->ReleaseDoubleArrayElements (env, retArray, values, 0);
230 pango_fc_font_unlock_face( font );
232 return retArray;
235 /* GetOutline code follows ****************************/
236 /********* Freetype callback functions *****************************/
238 static int _moveTo( const FT_Vector* to,
239 void *p)
241 JNIEnv *env;
242 jobject obj;
243 jclass cls;
244 jmethodID method;
245 jvalue values[2];
246 generalpath *path = (generalpath *) p;
248 env = path->env;
249 obj = path->obj;
251 values[0].f = (jfloat)(to->x * path->sx + path->px);
252 values[1].f = (jfloat)(to->y * path->sy + path->py);
254 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
255 method = (*env)->GetMethodID (env, cls, "moveTo", "(FF)V");
256 (*env)->CallVoidMethodA(env, obj, method, values );
258 return 0;
261 static int _lineTo( const FT_Vector* to,
262 void *p)
264 JNIEnv *env;
265 jobject obj;
266 jclass cls;
267 jmethodID method;
268 jvalue values[2];
269 generalpath *path = (generalpath *) p;
271 env = path->env;
272 obj = path->obj;
273 values[0].f = (jfloat)(to->x * path->sx + path->px);
274 values[1].f = (jfloat)(to->y * path->sy + path->py);
276 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
277 method = (*env)->GetMethodID (env, cls, "lineTo", "(FF)V");
278 (*env)->CallVoidMethodA(env, obj, method, values );
280 return 0;
283 static int _quadTo( const FT_Vector* cp,
284 const FT_Vector* to,
285 void *p)
287 JNIEnv *env;
288 jobject obj;
289 jclass cls;
290 jmethodID method;
291 jvalue values[4];
292 generalpath *path = (generalpath *) p;
294 env = path->env;
295 obj = path->obj;
296 values[0].f = (jfloat)(cp->x * path->sx + path->px);
297 values[1].f = (jfloat)(cp->y * path->sy + path->py);
298 values[2].f = (jfloat)(to->x * path->sx + path->px);
299 values[3].f = (jfloat)(to->y * path->sy + path->py);
301 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
302 method = (*env)->GetMethodID (env, cls, "quadTo", "(FFFF)V");
303 (*env)->CallVoidMethodA(env, obj, method, values );
305 return 0;
308 static int _curveTo( const FT_Vector* cp1,
309 const FT_Vector* cp2,
310 const FT_Vector* to,
311 void *p)
313 JNIEnv *env;
314 jobject obj;
315 jclass cls;
316 jmethodID method;
317 jvalue values[6];
318 generalpath *path = (generalpath *) p;
320 env = path->env;
321 obj = path->obj;
322 values[0].f = (jfloat)(cp1->x * path->sx + path->px);
323 values[1].f = (jfloat)(cp1->y * path->sy + path->py);
324 values[2].f = (jfloat)(cp2->x * path->sx + path->px);
325 values[3].f = (jfloat)(cp2->y * path->sy + path->py);
326 values[4].f = (jfloat)(to->x * path->sx + path->px);
327 values[5].f = (jfloat)(to->y * path->sy + path->py);
329 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
330 method = (*env)->GetMethodID (env, cls, "curveTo", "(FFFFFF)V");
331 (*env)->CallVoidMethodA(env, obj, method, values );
333 return 0;
337 JNIEXPORT jobject JNICALL
338 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
339 (JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
341 generalpath *path;
342 jobject gp;
343 FT_Outline_Funcs ftCallbacks =
345 (FT_Outline_MoveToFunc) _moveTo,
346 (FT_Outline_LineToFunc) _lineTo,
347 (FT_Outline_ConicToFunc) _quadTo,
348 (FT_Outline_CubicToFunc) _curveTo,
352 PangoFcFont *font;
353 FT_Face ft_face;
354 FT_Glyph glyph;
356 font = JLONG_TO_PTR(PangoFcFont, fnt);
357 ft_face = pango_fc_font_lock_face( font );
359 g_assert (ft_face != NULL);
361 path = g_malloc0 (sizeof (generalpath));
362 g_assert(path != NULL);
363 path->env = env;
365 path->px = path->py = 0.0;
366 path->sx = 1.0/64.0;
367 path->sy = -1.0/64.0;
369 { /* create a GeneralPath instance */
370 jclass cls;
371 jmethodID method;
373 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
374 method = (*env)->GetMethodID (env, cls, "<init>", "()V");
375 gp = path->obj = (*env)->NewObject (env, cls, method);
378 if(FT_Load_Glyph(ft_face,
379 (FT_UInt)(glyphIndex),
380 FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP) != 0)
382 pango_fc_font_unlock_face( font );
383 g_free(path);
384 return NULL;
387 FT_Get_Glyph( ft_face->glyph, &glyph );
388 if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
390 FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
391 &ftCallbacks, path);
393 else
395 char format[5];
397 format[0] = (glyph->format & 0xFF000000) >> 24;
398 format[1] = (glyph->format & 0x00FF0000) >> 16;
399 format[2] = (glyph->format & 0x0000FF00) >> 8;
400 format[3] = (glyph->format & 0x000000FF);
401 format[4] = '\0';
402 printf("WARNING: Unable to create outline for font %s %s of format %s\n",
403 ft_face->family_name, ft_face->style_name, format);
405 FT_Done_Glyph( glyph );
407 pango_fc_font_unlock_face( font );
409 g_free(path);
411 return gp;
414 JNIEXPORT void JNICALL
415 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_dispose
416 (JNIEnv *env, jobject obj __attribute__((unused)), jlongArray fontset)
418 PangoFcFont *font;
419 jlong *fontArray;
420 int i, length;
422 length = (*env)->GetArrayLength (env, fontset);
423 fontArray = (*env)->GetLongArrayElements (env, fontset, NULL);
425 gdk_threads_enter();
427 for( i = 0; i < length; i++ )
429 font = JLONG_TO_PTR(PangoFcFont, fontArray[i]);
430 g_object_unref(font);
433 gdk_threads_leave();
435 (*env)->ReleaseLongArrayElements (env, fontset, fontArray, 0);
438 JNIEXPORT jlong JNICALL
439 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getNativeFontPointer
440 (JNIEnv *env, jobject obj, jint n)
442 int i;
443 PangoFcFont *font = getFont(env, obj);
445 for (i = 0; i < n; i++)
446 g_object_ref(font);
448 return PTR_TO_JLONG(font);