Merged with mainline at revision 128810.
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_FreetypeGlyphVector.c
blobcea06f52d512527e7c04c6774f7aeaa1baaf4b11
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 jobject JNICALL
173 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getKerning
174 (JNIEnv *env, jobject obj __attribute__((unused)), jint rightGlyph, jint leftGlyph, jlong fnt)
176 FT_Face ft_face;
177 FT_Vector kern;
178 jclass cls;
179 jmethodID method;
180 jvalue values[2];
181 PangoFcFont *font;
183 font = JLONG_TO_PTR(PangoFcFont, fnt);
184 ft_face = pango_fc_font_lock_face( font );
185 g_assert (ft_face != NULL);
186 FT_Get_Kerning( ft_face, rightGlyph, leftGlyph, FT_KERNING_DEFAULT, &kern );
188 pango_fc_font_unlock_face( font );
190 values[0].d = (jdouble)kern.x/64.0;
191 values[1].d = (jdouble)kern.y/64.0;
193 cls = (*env)->FindClass (env, "java/awt/geom/Point2D$Double");
194 method = (*env)->GetMethodID (env, cls, "<init>", "(DD)V");
195 return (*env)->NewObjectA(env, cls, method, values);
198 JNIEXPORT jdoubleArray JNICALL
199 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative
200 (JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
202 FT_Face ft_face;
203 jdouble *values;
204 jdoubleArray retArray = NULL;
205 PangoFcFont *font;
207 font = JLONG_TO_PTR(PangoFcFont, fnt);
208 ft_face = pango_fc_font_lock_face( font );
210 g_assert (ft_face != NULL);
212 FT_Set_Transform( ft_face, NULL, NULL );
214 if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_NO_BITMAP ) != 0 )
216 pango_fc_font_unlock_face( font );
217 printf("Couldn't load glyph %i\n", glyphIndex);
218 return NULL;
221 retArray = (*env)->NewDoubleArray (env, 8);
222 values = (*env)->GetDoubleArrayElements (env, retArray, NULL);
224 values[0] = 0;
225 values[1] = (jdouble)ft_face->glyph->advance.x/64.0;
226 values[2] = (jdouble)ft_face->glyph->advance.y/64.0;
227 values[3] = (jdouble)ft_face->glyph->metrics.horiBearingX/64.0;
228 values[4] = -(jdouble)ft_face->glyph->metrics.horiBearingY/64.0;
229 values[5] = (jdouble)ft_face->glyph->metrics.width/64.0;
230 values[6] = (jdouble)ft_face->glyph->metrics.height/64.0;
231 values[7] = 0;
233 (*env)->ReleaseDoubleArrayElements (env, retArray, values, 0);
234 pango_fc_font_unlock_face( font );
236 return retArray;
239 /* GetOutline code follows ****************************/
240 /********* Freetype callback functions *****************************/
242 static int _moveTo( const FT_Vector* to,
243 void *p)
245 JNIEnv *env;
246 jobject obj;
247 jclass cls;
248 jmethodID method;
249 jvalue values[2];
250 generalpath *path = (generalpath *) p;
252 env = path->env;
253 obj = path->obj;
255 values[0].f = (jfloat)(to->x * path->sx + path->px);
256 values[1].f = (jfloat)(to->y * path->sy + path->py);
258 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
259 method = (*env)->GetMethodID (env, cls, "moveTo", "(FF)V");
260 (*env)->CallVoidMethodA(env, obj, method, values );
262 return 0;
265 static int _lineTo( const FT_Vector* to,
266 void *p)
268 JNIEnv *env;
269 jobject obj;
270 jclass cls;
271 jmethodID method;
272 jvalue values[2];
273 generalpath *path = (generalpath *) p;
275 env = path->env;
276 obj = path->obj;
277 values[0].f = (jfloat)(to->x * path->sx + path->px);
278 values[1].f = (jfloat)(to->y * path->sy + path->py);
280 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
281 method = (*env)->GetMethodID (env, cls, "lineTo", "(FF)V");
282 (*env)->CallVoidMethodA(env, obj, method, values );
284 return 0;
287 static int _quadTo( const FT_Vector* cp,
288 const FT_Vector* to,
289 void *p)
291 JNIEnv *env;
292 jobject obj;
293 jclass cls;
294 jmethodID method;
295 jvalue values[4];
296 generalpath *path = (generalpath *) p;
298 env = path->env;
299 obj = path->obj;
300 values[0].f = (jfloat)(cp->x * path->sx + path->px);
301 values[1].f = (jfloat)(cp->y * path->sy + path->py);
302 values[2].f = (jfloat)(to->x * path->sx + path->px);
303 values[3].f = (jfloat)(to->y * path->sy + path->py);
305 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
306 method = (*env)->GetMethodID (env, cls, "quadTo", "(FFFF)V");
307 (*env)->CallVoidMethodA(env, obj, method, values );
309 return 0;
312 static int _curveTo( const FT_Vector* cp1,
313 const FT_Vector* cp2,
314 const FT_Vector* to,
315 void *p)
317 JNIEnv *env;
318 jobject obj;
319 jclass cls;
320 jmethodID method;
321 jvalue values[6];
322 generalpath *path = (generalpath *) p;
324 env = path->env;
325 obj = path->obj;
326 values[0].f = (jfloat)(cp1->x * path->sx + path->px);
327 values[1].f = (jfloat)(cp1->y * path->sy + path->py);
328 values[2].f = (jfloat)(cp2->x * path->sx + path->px);
329 values[3].f = (jfloat)(cp2->y * path->sy + path->py);
330 values[4].f = (jfloat)(to->x * path->sx + path->px);
331 values[5].f = (jfloat)(to->y * path->sy + path->py);
333 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
334 method = (*env)->GetMethodID (env, cls, "curveTo", "(FFFFFF)V");
335 (*env)->CallVoidMethodA(env, obj, method, values );
337 return 0;
341 JNIEXPORT jobject JNICALL
342 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
343 (JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
345 generalpath *path;
346 jobject gp;
347 FT_Outline_Funcs ftCallbacks =
349 (FT_Outline_MoveToFunc) _moveTo,
350 (FT_Outline_LineToFunc) _lineTo,
351 (FT_Outline_ConicToFunc) _quadTo,
352 (FT_Outline_CubicToFunc) _curveTo,
356 PangoFcFont *font;
357 FT_Face ft_face;
358 FT_Glyph glyph;
360 font = JLONG_TO_PTR(PangoFcFont, fnt);
361 ft_face = pango_fc_font_lock_face( font );
363 g_assert (ft_face != NULL);
365 path = g_malloc0 (sizeof (generalpath));
366 g_assert(path != NULL);
367 path->env = env;
369 path->px = path->py = 0.0;
370 path->sx = 1.0/64.0;
371 path->sy = -1.0/64.0;
373 { /* create a GeneralPath instance */
374 jclass cls;
375 jmethodID method;
377 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
378 method = (*env)->GetMethodID (env, cls, "<init>", "()V");
379 gp = path->obj = (*env)->NewObject (env, cls, method);
382 if(FT_Load_Glyph(ft_face,
383 (FT_UInt)(glyphIndex),
384 FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP) != 0)
386 pango_fc_font_unlock_face( font );
387 g_free(path);
388 return NULL;
391 FT_Get_Glyph( ft_face->glyph, &glyph );
392 FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
393 &ftCallbacks, path);
394 FT_Done_Glyph( glyph );
396 pango_fc_font_unlock_face( font );
398 g_free(path);
400 return gp;
403 JNIEXPORT void JNICALL
404 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_dispose
405 (JNIEnv *env, jobject obj __attribute__((unused)), jlongArray fontset)
407 PangoFcFont *font;
408 jlong *fontArray;
409 int i, length;
411 length = (*env)->GetArrayLength (env, fontset);
412 fontArray = (*env)->GetLongArrayElements (env, fontset, NULL);
414 gdk_threads_enter();
416 for( i = 0; i < length; i++ )
418 font = JLONG_TO_PTR(PangoFcFont, fontArray[i]);
419 g_object_unref(font);
422 gdk_threads_leave();
424 (*env)->ReleaseLongArrayElements (env, fontset, fontArray, 0);
427 JNIEXPORT jlong JNICALL
428 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getNativeFontPointer
429 (JNIEnv *env, jobject obj, jint n)
431 int i;
432 PangoFcFont *font = getFont(env, obj);
434 for (i = 0; i < n; i++)
435 g_object_ref(font);
437 return PTR_TO_JLONG(font);