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>
45 #include <freetype/ftglyph.h>
46 #include <freetype/ftoutln.h>
49 #include "gnu_java_awt_peer_gtk_FreetypeGlyphVector.h"
50 #include "cairographics2d.h"
63 getFont(JNIEnv
*env
, jobject obj
)
68 struct peerfont
*pfont
;
70 cls
= (*env
)->GetObjectClass (env
, obj
);
71 fid
= (*env
)->GetFieldID (env
, cls
, "peer",
72 "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
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
;
86 getFontSet(JNIEnv
*env
, jobject obj
)
91 struct peerfont
*pfont
;
93 cls
= (*env
)->GetObjectClass (env
, obj
);
94 fid
= (*env
)->GetFieldID (env
, cls
, "peer",
95 "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
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
,
113 PangoFcFont
*default_font
, *current_font
;
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... */
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
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
);
151 current_font
= (PangoFcFont
*)pango_fontset_get_font(pfs
, cpvals
[i
]);
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
);
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
)
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
)
204 jdoubleArray retArray
= NULL
;
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
);
221 retArray
= (*env
)->NewDoubleArray (env
, 8);
222 values
= (*env
)->GetDoubleArrayElements (env
, retArray
, NULL
);
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;
233 (*env
)->ReleaseDoubleArrayElements (env
, retArray
, values
, 0);
234 pango_fc_font_unlock_face( font
);
239 /* GetOutline code follows ****************************/
240 /********* Freetype callback functions *****************************/
242 static int _moveTo( const FT_Vector
* to
,
250 generalpath
*path
= (generalpath
*) p
;
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
);
265 static int _lineTo( const FT_Vector
* to
,
273 generalpath
*path
= (generalpath
*) p
;
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
);
287 static int _quadTo( const FT_Vector
* cp
,
296 generalpath
*path
= (generalpath
*) p
;
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
);
312 static int _curveTo( const FT_Vector
* cp1
,
313 const FT_Vector
* cp2
,
322 generalpath
*path
= (generalpath
*) p
;
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
);
341 JNIEXPORT jobject JNICALL
342 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
343 (JNIEnv
*env
, jobject obj
__attribute__((unused
)), jint glyphIndex
, jlong fnt
)
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
,
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
);
369 path
->px
= path
->py
= 0.0;
371 path
->sy
= -1.0/64.0;
373 { /* create a GeneralPath instance */
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
);
391 FT_Get_Glyph( ft_face
->glyph
, &glyph
);
392 FT_Outline_Decompose (&(((FT_OutlineGlyph
)glyph
)->outline
),
394 FT_Done_Glyph( glyph
);
396 pango_fc_font_unlock_face( font
);
403 JNIEXPORT
void JNICALL
404 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_dispose
405 (JNIEnv
*env
, jobject obj
__attribute__((unused
)), jlongArray fontset
)
411 length
= (*env
)->GetArrayLength (env
, fontset
);
412 fontArray
= (*env
)->GetLongArrayElements (env
, fontset
, NULL
);
416 for( i
= 0; i
< length
; i
++ )
418 font
= JLONG_TO_PTR(PangoFcFont
, fontArray
[i
]);
419 g_object_unref(font
);
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
)
432 PangoFcFont
*font
= getFont(env
, obj
);
434 for (i
= 0; i
< n
; i
++)
437 return PTR_TO_JLONG(font
);