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)
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
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
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
42 #include <pango/pango.h>
43 #include <pango/pangoft2.h>
44 #include <pango/pangofc-font.h>
50 #include "gnu_java_awt_peer_gtk_FreetypeGlyphVector.h"
51 #include "cairographics2d.h"
64 getFont(JNIEnv *env, jobject obj)
69 struct peerfont *pfont;
71 cls = (*env)->GetObjectClass (env, obj);
72 fid = (*env)->GetFieldID (env, cls, "peer",
73 "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
76 data = (*env)->GetObjectField (env, obj, fid);
77 g_assert (data != NULL);
79 pfont = (struct peerfont *) gtkpeer_get_font(env, data);
80 g_assert (pfont != NULL);
81 g_assert (pfont->font != NULL);
83 return (PangoFcFont *)pfont->font;
87 getFontSet(JNIEnv *env, jobject obj)
92 struct peerfont *pfont;
94 cls = (*env)->GetObjectClass (env, obj);
95 fid = (*env)->GetFieldID (env, cls, "peer",
96 "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
99 data = (*env)->GetObjectField (env, obj, fid);
100 g_assert (data != NULL);
102 pfont = (struct peerfont *) gtkpeer_get_font (env, data);
103 g_assert (pfont != NULL);
104 g_assert (pfont->font != NULL);
106 return (PangoFontset *)pfont->set;
109 JNIEXPORT void JNICALL
110 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphs
111 (JNIEnv *env, jobject obj, jintArray codepoints, jintArray glyphs,
114 PangoFcFont *default_font, *current_font;
120 /* Set up default font and fontset */
121 default_font = getFont(env, obj);
122 current_font = default_font;
123 pfs = getFontSet(env, obj);
125 /* Retrieve string information */
126 length = (*env)->GetArrayLength (env, codepoints);
127 cpvals = (*env)->GetIntArrayElements (env, codepoints, NULL);
129 jint *glyphArray = (*env)->GetIntArrayElements (env, glyphs, NULL);
130 jlong *fontArray = (*env)->GetLongArrayElements (env, fonts, NULL);
132 /* A design goal of Pango is to be threadsafe, but it's admitted that it is
133 * not actually threadsafe at the moment. Using gdk locking here to be safe,
134 * but I don't know if if actually helps at all... */
137 for( i = 0; i < length; i++ )
139 /* Ensure the current font has the requested character; if it doesn't,
140 * try the default font before pulling a new font out of the fontset.
141 * Once chosen, a font will be used until a character not in the font is
143 if (!pango_fc_font_has_char(current_font, cpvals[i]))
145 if (pango_fc_font_has_char(default_font, cpvals[i]))
147 current_font = default_font;
148 g_object_ref(current_font);
152 current_font = (PangoFcFont*)pango_fontset_get_font(pfs, cpvals[i]);
157 g_object_ref(current_font);
160 /* Get glyph, and store both glyph and pointer to font */
161 glyphArray[i] = (int)pango_fc_font_get_glyph(current_font,
162 (gunichar)cpvals[i]);
163 fontArray[i] = PTR_TO_JLONG(current_font);
168 (*env)->ReleaseIntArrayElements (env, glyphs, glyphArray, 0);
169 (*env)->ReleaseIntArrayElements (env, codepoints, cpvals, 0);
170 (*env)->ReleaseLongArrayElements (env, fonts, fontArray, 0);
173 JNIEXPORT void JNICALL
174 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getKerning
175 (JNIEnv *env, jobject obj __attribute__((unused)), jint rightGlyph,
176 jint leftGlyph, jlong fnt, jfloatArray p)
182 font = JLONG_TO_PTR(PangoFcFont, fnt);
183 ft_face = pango_fc_font_lock_face( font );
184 g_assert (ft_face != NULL);
185 FT_Get_Kerning( ft_face, rightGlyph, leftGlyph, FT_KERNING_DEFAULT, &kern );
187 pango_fc_font_unlock_face( font );
189 jfloat *pelements = (*env)->GetPrimitiveArrayCritical(env, p, NULL);
190 pelements[0] = (jfloat)kern.x/64.0;
191 pelements[1] = (jfloat)kern.y/64.0;
192 (*env)->ReleasePrimitiveArrayCritical (env, p, pelements, 0);
195 JNIEXPORT jdoubleArray JNICALL
196 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative
197 (JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
201 jdoubleArray retArray = NULL;
204 font = JLONG_TO_PTR(PangoFcFont, fnt);
205 ft_face = pango_fc_font_lock_face( font );
207 g_assert (ft_face != NULL);
209 FT_Set_Transform( ft_face, NULL, NULL );
211 if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_NO_BITMAP ) != 0 )
213 pango_fc_font_unlock_face( font );
214 printf("Couldn't load glyph %i\n", glyphIndex);
218 retArray = (*env)->NewDoubleArray (env, 8);
219 values = (*env)->GetDoubleArrayElements (env, retArray, NULL);
222 values[1] = (jdouble)ft_face->glyph->advance.x/64.0;
223 values[2] = (jdouble)ft_face->glyph->advance.y/64.0;
224 values[3] = (jdouble)ft_face->glyph->metrics.horiBearingX/64.0;
225 values[4] = -(jdouble)ft_face->glyph->metrics.horiBearingY/64.0;
226 values[5] = (jdouble)ft_face->glyph->metrics.width/64.0;
227 values[6] = (jdouble)ft_face->glyph->metrics.height/64.0;
230 (*env)->ReleaseDoubleArrayElements (env, retArray, values, 0);
231 pango_fc_font_unlock_face( font );
236 /* GetOutline code follows ****************************/
237 /********* Freetype callback functions *****************************/
239 static int _moveTo( const FT_Vector* to,
247 generalpath *path = (generalpath *) p;
252 values[0].f = (jfloat)(to->x * path->sx + path->px);
253 values[1].f = (jfloat)(to->y * path->sy + path->py);
255 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
256 method = (*env)->GetMethodID (env, cls, "moveTo", "(FF)V");
257 (*env)->CallVoidMethodA(env, obj, method, values );
262 static int _lineTo( const FT_Vector* to,
270 generalpath *path = (generalpath *) p;
274 values[0].f = (jfloat)(to->x * path->sx + path->px);
275 values[1].f = (jfloat)(to->y * path->sy + path->py);
277 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
278 method = (*env)->GetMethodID (env, cls, "lineTo", "(FF)V");
279 (*env)->CallVoidMethodA(env, obj, method, values );
284 static int _quadTo( const FT_Vector* cp,
293 generalpath *path = (generalpath *) p;
297 values[0].f = (jfloat)(cp->x * path->sx + path->px);
298 values[1].f = (jfloat)(cp->y * path->sy + path->py);
299 values[2].f = (jfloat)(to->x * path->sx + path->px);
300 values[3].f = (jfloat)(to->y * path->sy + path->py);
302 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
303 method = (*env)->GetMethodID (env, cls, "quadTo", "(FFFF)V");
304 (*env)->CallVoidMethodA(env, obj, method, values );
309 static int _curveTo( const FT_Vector* cp1,
310 const FT_Vector* cp2,
319 generalpath *path = (generalpath *) p;
323 values[0].f = (jfloat)(cp1->x * path->sx + path->px);
324 values[1].f = (jfloat)(cp1->y * path->sy + path->py);
325 values[2].f = (jfloat)(cp2->x * path->sx + path->px);
326 values[3].f = (jfloat)(cp2->y * path->sy + path->py);
327 values[4].f = (jfloat)(to->x * path->sx + path->px);
328 values[5].f = (jfloat)(to->y * path->sy + path->py);
330 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
331 method = (*env)->GetMethodID (env, cls, "curveTo", "(FFFFFF)V");
332 (*env)->CallVoidMethodA(env, obj, method, values );
338 JNIEXPORT jobject JNICALL
339 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
340 (JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
344 FT_Outline_Funcs ftCallbacks =
346 (FT_Outline_MoveToFunc) _moveTo,
347 (FT_Outline_LineToFunc) _lineTo,
348 (FT_Outline_ConicToFunc) _quadTo,
349 (FT_Outline_CubicToFunc) _curveTo,
357 font = JLONG_TO_PTR(PangoFcFont, fnt);
358 ft_face = pango_fc_font_lock_face( font );
360 g_assert (ft_face != NULL);
362 path = g_malloc0 (sizeof (generalpath));
363 g_assert(path != NULL);
366 path->px = path->py = 0.0;
368 path->sy = -1.0/64.0;
370 { /* create a GeneralPath instance */
374 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
375 method = (*env)->GetMethodID (env, cls, "<init>", "()V");
376 gp = path->obj = (*env)->NewObject (env, cls, method);
379 if(FT_Load_Glyph(ft_face,
380 (FT_UInt)(glyphIndex),
381 FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP) != 0)
383 pango_fc_font_unlock_face( font );
388 FT_Get_Glyph( ft_face->glyph, &glyph );
389 if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
391 FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
398 format[0] = (glyph->format & 0xFF000000) >> 24;
399 format[1] = (glyph->format & 0x00FF0000) >> 16;
400 format[2] = (glyph->format & 0x0000FF00) >> 8;
401 format[3] = (glyph->format & 0x000000FF);
403 printf("WARNING: Unable to create outline for font %s %s of format %s\n",
404 ft_face->family_name, ft_face->style_name, format);
406 FT_Done_Glyph( glyph );
408 pango_fc_font_unlock_face( font );
415 JNIEXPORT void JNICALL
416 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_dispose
417 (JNIEnv *env, jobject obj __attribute__((unused)), jlongArray fontset)
423 length = (*env)->GetArrayLength (env, fontset);
424 fontArray = (*env)->GetLongArrayElements (env, fontset, NULL);
428 for( i = 0; i < length; i++ )
430 font = JLONG_TO_PTR(PangoFcFont, fontArray[i]);
431 g_object_unref(font);
436 (*env)->ReleaseLongArrayElements (env, fontset, fontArray, 0);
439 JNIEXPORT jlong JNICALL
440 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getNativeFontPointer
441 (JNIEnv *env, jobject obj, jint n)
444 PangoFcFont *font = getFont(env, obj);
446 for (i = 0; i < n; i++)
449 return PTR_TO_JLONG(font);