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
)
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
)
200 jdoubleArray retArray
= NULL
;
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
);
217 retArray
= (*env
)->NewDoubleArray (env
, 8);
218 values
= (*env
)->GetDoubleArrayElements (env
, retArray
, NULL
);
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;
229 (*env
)->ReleaseDoubleArrayElements (env
, retArray
, values
, 0);
230 pango_fc_font_unlock_face( font
);
235 /* GetOutline code follows ****************************/
236 /********* Freetype callback functions *****************************/
238 static int _moveTo( const FT_Vector
* to
,
246 generalpath
*path
= (generalpath
*) p
;
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
);
261 static int _lineTo( const FT_Vector
* to
,
269 generalpath
*path
= (generalpath
*) p
;
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
);
283 static int _quadTo( const FT_Vector
* cp
,
292 generalpath
*path
= (generalpath
*) p
;
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
);
308 static int _curveTo( const FT_Vector
* cp1
,
309 const FT_Vector
* cp2
,
318 generalpath
*path
= (generalpath
*) p
;
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
);
337 JNIEXPORT jobject JNICALL
338 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
339 (JNIEnv
*env
, jobject obj
__attribute__((unused
)), jint glyphIndex
, jlong fnt
)
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
,
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
);
365 path
->px
= path
->py
= 0.0;
367 path
->sy
= -1.0/64.0;
369 { /* create a GeneralPath instance */
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
);
387 FT_Get_Glyph( ft_face
->glyph
, &glyph
);
388 if (glyph
->format
== FT_GLYPH_FORMAT_OUTLINE
)
390 FT_Outline_Decompose (&(((FT_OutlineGlyph
)glyph
)->outline
),
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);
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
);
414 JNIEXPORT
void JNICALL
415 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_dispose
416 (JNIEnv
*env
, jobject obj
__attribute__((unused
)), jlongArray fontset
)
422 length
= (*env
)->GetArrayLength (env
, fontset
);
423 fontArray
= (*env
)->GetLongArrayElements (env
, fontset
, NULL
);
427 for( i
= 0; i
< length
; i
++ )
429 font
= JLONG_TO_PTR(PangoFcFont
, fontArray
[i
]);
430 g_object_unref(font
);
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
)
443 PangoFcFont
*font
= getFont(env
, obj
);
445 for (i
= 0; i
< n
; i
++)
448 return PTR_TO_JLONG(font
);