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
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
)
184 font
= JLONG_TO_PTR(PangoFcFont
, fnt
);
185 ft_face
= pango_fc_font_lock_face( font
);
186 g_assert (ft_face
!= NULL
);
187 FT_Get_Kerning( ft_face
, rightGlyph
, leftGlyph
, FT_KERNING_DEFAULT
, &kern
);
189 pango_fc_font_unlock_face( font
);
191 jfloat
*pelements
= (*env
)->GetPrimitiveArrayCritical(env
, p
, NULL
);
192 pelements
[0] = (jfloat
)kern
.x
/64.0;
193 pelements
[1] = (jfloat
)kern
.y
/64.0;
194 (*env
)->ReleasePrimitiveArrayCritical (env
, p
, pelements
, 0);
197 JNIEXPORT jdoubleArray JNICALL
198 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative
199 (JNIEnv
*env
, jobject obj
__attribute__((unused
)), jint glyphIndex
, jlong fnt
)
203 jdoubleArray retArray
= NULL
;
206 font
= JLONG_TO_PTR(PangoFcFont
, fnt
);
207 ft_face
= pango_fc_font_lock_face( font
);
209 g_assert (ft_face
!= NULL
);
211 FT_Set_Transform( ft_face
, NULL
, NULL
);
213 if( FT_Load_Glyph( ft_face
, glyphIndex
, FT_LOAD_NO_BITMAP
) != 0 )
215 pango_fc_font_unlock_face( font
);
216 printf("Couldn't load glyph %i\n", glyphIndex
);
220 retArray
= (*env
)->NewDoubleArray (env
, 8);
221 values
= (*env
)->GetDoubleArrayElements (env
, retArray
, NULL
);
224 values
[1] = (jdouble
)ft_face
->glyph
->advance
.x
/64.0;
225 values
[2] = (jdouble
)ft_face
->glyph
->advance
.y
/64.0;
226 values
[3] = (jdouble
)ft_face
->glyph
->metrics
.horiBearingX
/64.0;
227 values
[4] = -(jdouble
)ft_face
->glyph
->metrics
.horiBearingY
/64.0;
228 values
[5] = (jdouble
)ft_face
->glyph
->metrics
.width
/64.0;
229 values
[6] = (jdouble
)ft_face
->glyph
->metrics
.height
/64.0;
232 (*env
)->ReleaseDoubleArrayElements (env
, retArray
, values
, 0);
233 pango_fc_font_unlock_face( font
);
238 /* GetOutline code follows ****************************/
239 /********* Freetype callback functions *****************************/
241 static int _moveTo( const FT_Vector
* to
,
249 generalpath
*path
= (generalpath
*) p
;
254 values
[0].f
= (jfloat
)(to
->x
* path
->sx
+ path
->px
);
255 values
[1].f
= (jfloat
)(to
->y
* path
->sy
+ path
->py
);
257 cls
= (*env
)->FindClass (env
, "java/awt/geom/GeneralPath");
258 method
= (*env
)->GetMethodID (env
, cls
, "moveTo", "(FF)V");
259 (*env
)->CallVoidMethodA(env
, obj
, method
, values
);
264 static int _lineTo( const FT_Vector
* to
,
272 generalpath
*path
= (generalpath
*) p
;
276 values
[0].f
= (jfloat
)(to
->x
* path
->sx
+ path
->px
);
277 values
[1].f
= (jfloat
)(to
->y
* path
->sy
+ path
->py
);
279 cls
= (*env
)->FindClass (env
, "java/awt/geom/GeneralPath");
280 method
= (*env
)->GetMethodID (env
, cls
, "lineTo", "(FF)V");
281 (*env
)->CallVoidMethodA(env
, obj
, method
, values
);
286 static int _quadTo( const FT_Vector
* cp
,
295 generalpath
*path
= (generalpath
*) p
;
299 values
[0].f
= (jfloat
)(cp
->x
* path
->sx
+ path
->px
);
300 values
[1].f
= (jfloat
)(cp
->y
* path
->sy
+ path
->py
);
301 values
[2].f
= (jfloat
)(to
->x
* path
->sx
+ path
->px
);
302 values
[3].f
= (jfloat
)(to
->y
* path
->sy
+ path
->py
);
304 cls
= (*env
)->FindClass (env
, "java/awt/geom/GeneralPath");
305 method
= (*env
)->GetMethodID (env
, cls
, "quadTo", "(FFFF)V");
306 (*env
)->CallVoidMethodA(env
, obj
, method
, values
);
311 static int _curveTo( const FT_Vector
* cp1
,
312 const FT_Vector
* cp2
,
321 generalpath
*path
= (generalpath
*) p
;
325 values
[0].f
= (jfloat
)(cp1
->x
* path
->sx
+ path
->px
);
326 values
[1].f
= (jfloat
)(cp1
->y
* path
->sy
+ path
->py
);
327 values
[2].f
= (jfloat
)(cp2
->x
* path
->sx
+ path
->px
);
328 values
[3].f
= (jfloat
)(cp2
->y
* path
->sy
+ path
->py
);
329 values
[4].f
= (jfloat
)(to
->x
* path
->sx
+ path
->px
);
330 values
[5].f
= (jfloat
)(to
->y
* path
->sy
+ path
->py
);
332 cls
= (*env
)->FindClass (env
, "java/awt/geom/GeneralPath");
333 method
= (*env
)->GetMethodID (env
, cls
, "curveTo", "(FFFFFF)V");
334 (*env
)->CallVoidMethodA(env
, obj
, method
, values
);
340 JNIEXPORT jobject JNICALL
341 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
342 (JNIEnv
*env
, jobject obj
__attribute__((unused
)), jint glyphIndex
, jlong fnt
)
346 FT_Outline_Funcs ftCallbacks
=
348 (FT_Outline_MoveToFunc
) _moveTo
,
349 (FT_Outline_LineToFunc
) _lineTo
,
350 (FT_Outline_ConicToFunc
) _quadTo
,
351 (FT_Outline_CubicToFunc
) _curveTo
,
359 font
= JLONG_TO_PTR(PangoFcFont
, fnt
);
360 ft_face
= pango_fc_font_lock_face( font
);
362 g_assert (ft_face
!= NULL
);
364 path
= g_malloc0 (sizeof (generalpath
));
365 g_assert(path
!= NULL
);
368 path
->px
= path
->py
= 0.0;
370 path
->sy
= -1.0/64.0;
372 { /* create a GeneralPath instance */
376 cls
= (*env
)->FindClass (env
, "java/awt/geom/GeneralPath");
377 method
= (*env
)->GetMethodID (env
, cls
, "<init>", "()V");
378 gp
= path
->obj
= (*env
)->NewObject (env
, cls
, method
);
381 if(FT_Load_Glyph(ft_face
,
382 (FT_UInt
)(glyphIndex
),
383 FT_LOAD_DEFAULT
| FT_LOAD_NO_BITMAP
) != 0)
385 pango_fc_font_unlock_face( font
);
390 FT_Get_Glyph( ft_face
->glyph
, &glyph
);
391 FT_Outline_Decompose (&(((FT_OutlineGlyph
)glyph
)->outline
),
393 FT_Done_Glyph( glyph
);
395 pango_fc_font_unlock_face( font
);
402 JNIEXPORT
void JNICALL
403 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_dispose
404 (JNIEnv
*env
, jobject obj
__attribute__((unused
)), jlongArray fontset
)
410 length
= (*env
)->GetArrayLength (env
, fontset
);
411 fontArray
= (*env
)->GetLongArrayElements (env
, fontset
, NULL
);
415 for( i
= 0; i
< length
; i
++ )
417 font
= JLONG_TO_PTR(PangoFcFont
, fontArray
[i
]);
418 g_object_unref(font
);
423 (*env
)->ReleaseLongArrayElements (env
, fontset
, fontArray
, 0);
426 JNIEXPORT jlong JNICALL
427 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getNativeFontPointer
428 (JNIEnv
*env
, jobject obj
, jint n
)
431 PangoFcFont
*font
= getFont(env
, obj
);
433 for (i
= 0; i
< n
; i
++)
436 return PTR_TO_JLONG(font
);