OSDN Git Service

2006-06-13 Thomas Fitzsimmons <fitzsim@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_FreetypeGlyphVector.c
1 /* gnu_java_awt_FreetypeGlyphVector.c
2    Copyright (C) 2006  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
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.
10
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.
15
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.
20
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.
25
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. */
37
38 #include <jni.h>
39 #include <gtk/gtk.h>
40 #include <string.h>
41 #include <pango/pango.h>
42 #include <pango/pangoft2.h>
43 #include <pango/pangofc-font.h>
44 #include <freetype/ftglyph.h>
45 #include <freetype/ftoutln.h>
46 #include "native_state.h"
47 #include "gdkfont.h"
48 #include "gnu_java_awt_peer_gtk_FreetypeGlyphVector.h"
49 #include "cairographics2d.h"
50
51 typedef struct gp
52 {
53   JNIEnv *env;
54   jobject obj;
55   double px;
56   double py;
57   double sx;
58   double sy;
59 } generalpath ;
60
61 static PangoFcFont *
62 getFont(JNIEnv *env, jobject obj)
63 {
64   jfieldID fid;
65   jobject data;
66   jclass cls;
67   struct peerfont *pfont;
68
69   cls = (*env)->GetObjectClass (env, obj);
70   fid = (*env)->GetFieldID (env, cls, "peer", 
71                                  "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
72   g_assert (fid != 0);
73
74   data = (*env)->GetObjectField (env, obj, fid);
75   g_assert (data != NULL);
76
77   pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, data);
78   g_assert (pfont != NULL);
79   g_assert (pfont->font != NULL);
80
81   return (PangoFcFont *)pfont->font;
82 }
83
84 JNIEXPORT jintArray JNICALL 
85 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphs
86   (JNIEnv *env, jobject obj, jintArray codepoints)
87 {
88   FT_Face ft_face;
89   jintArray retArray;
90   PangoFcFont *font;
91   jint *values, *cpvals;
92   jint length;
93   int i;
94
95   font = getFont(env, obj);
96
97   ft_face = pango_fc_font_lock_face( font );
98   g_assert (ft_face != NULL);
99
100   length = (*env)->GetArrayLength (env, codepoints);
101   cpvals = (*env)->GetIntArrayElements (env, codepoints, NULL);
102
103   retArray = (*env)->NewIntArray (env, length);
104   values = (*env)->GetIntArrayElements (env, retArray, NULL);
105
106   for( i = 0; i < length; i++ )
107     values[i] = FT_Get_Char_Index( ft_face, cpvals[i] );
108
109   (*env)->ReleaseIntArrayElements (env, retArray, values, 0);
110   (*env)->ReleaseIntArrayElements (env, codepoints, cpvals, 0);
111
112   pango_fc_font_unlock_face (font);
113
114   return retArray;
115 }
116
117 JNIEXPORT jobject JNICALL 
118 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getKerning
119 (JNIEnv *env, jobject obj, jint rightGlyph, jint leftGlyph)
120 {
121   FT_Face ft_face;
122   FT_Vector kern;
123   jclass cls;
124   jmethodID method;
125   jvalue values[2];
126   PangoFcFont *font;
127
128   font = getFont(env, obj);
129   ft_face = pango_fc_font_lock_face( font );
130   g_assert (ft_face != NULL);
131   FT_Get_Kerning( ft_face, rightGlyph, leftGlyph, FT_KERNING_DEFAULT, &kern );
132
133   pango_fc_font_unlock_face( font );
134
135   values[0].d = (jdouble)kern.x/64.0;
136   values[1].d = (jdouble)kern.y/64.0;
137
138   cls = (*env)->FindClass (env, "java/awt/geom/Point2D$Double");
139   method = (*env)->GetMethodID (env, cls, "<init>", "(DD)V");
140   return (*env)->NewObjectA(env, cls, method, values);
141 }
142
143 JNIEXPORT jdoubleArray JNICALL 
144 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative
145 (JNIEnv *env, jobject obj, jint glyphIndex )
146 {
147   FT_Face ft_face;
148   jdouble *values;
149   jdoubleArray retArray = NULL;
150   PangoFcFont *font;
151
152   font = getFont(env, obj);
153   ft_face = pango_fc_font_lock_face( font );
154
155   g_assert (ft_face != NULL);
156
157   FT_Set_Transform( ft_face, NULL, NULL );
158
159   if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_NO_BITMAP ) != 0 )
160     {
161       pango_fc_font_unlock_face( font );
162       printf("Couldn't load glyph %i\n", glyphIndex);
163       return NULL;
164     }
165
166   retArray = (*env)->NewDoubleArray (env, 8);
167   values = (*env)->GetDoubleArrayElements (env, retArray, NULL);
168
169   values[0] = 0;
170   values[1] = (jdouble)ft_face->glyph->advance.x/64.0;
171   values[2] = (jdouble)ft_face->glyph->advance.y/64.0;
172   values[3] = (jdouble)ft_face->glyph->metrics.horiBearingX/64.0;
173   values[4] = -(jdouble)ft_face->glyph->metrics.horiBearingY/64.0;
174   values[5] = (jdouble)ft_face->glyph->metrics.width/64.0;
175   values[6] = (jdouble)ft_face->glyph->metrics.height/64.0;
176   values[7] = 0;
177
178   (*env)->ReleaseDoubleArrayElements (env, retArray, values, 0);
179   pango_fc_font_unlock_face( font );
180
181   return retArray;
182 }
183
184 /* GetOutline code follows ****************************/
185 /********* Freetype callback functions *****************************/
186
187 static int _moveTo( const FT_Vector* to,
188                     void *p)
189 {
190   JNIEnv *env;
191   jobject obj;
192   jclass cls;
193   jmethodID method;
194   jvalue values[2];
195   generalpath *path = (generalpath *) p;
196
197   env = path->env;
198   obj = path->obj;
199
200   values[0].f = (jfloat)(to->x * path->sx + path->px);
201   values[1].f = (jfloat)(to->y * path->sy + path->py);
202
203   cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
204   method = (*env)->GetMethodID (env, cls, "moveTo", "(FF)V");
205   (*env)->CallVoidMethodA(env, obj, method, values );
206
207   return 0;
208 }
209
210 static int _lineTo( const FT_Vector*  to,
211                     void *p)
212 {
213   JNIEnv *env;
214   jobject obj;
215   jclass cls;
216   jmethodID method;
217   jvalue values[2];
218   generalpath *path = (generalpath *) p;
219
220   env = path->env;
221   obj = path->obj; 
222   values[0].f = (jfloat)(to->x * path->sx + path->px);
223   values[1].f = (jfloat)(to->y * path->sy + path->py);
224
225   cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
226   method = (*env)->GetMethodID (env, cls, "lineTo", "(FF)V");
227   (*env)->CallVoidMethodA(env, obj, method, values );
228
229   return 0;
230 }
231
232 static int _quadTo( const FT_Vector*  cp,
233                     const FT_Vector*  to,
234                     void *p)
235 {
236   JNIEnv *env;
237   jobject obj;
238   jclass cls;
239   jmethodID method;
240   jvalue values[4];
241   generalpath *path = (generalpath *) p;
242
243   env = path->env;
244   obj = path->obj;
245   values[0].f = (jfloat)(cp->x * path->sx + path->px);
246   values[1].f = (jfloat)(cp->y * path->sy + path->py);
247   values[2].f = (jfloat)(to->x * path->sx + path->px);
248   values[3].f = (jfloat)(to->y * path->sy + path->py);
249
250   cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
251   method = (*env)->GetMethodID (env, cls, "quadTo", "(FFFF)V");
252   (*env)->CallVoidMethodA(env, obj, method, values );
253
254   return 0;
255 }
256
257 static int _curveTo( const FT_Vector*  cp1,
258                      const FT_Vector*  cp2,
259                      const FT_Vector*  to,
260                      void *p)
261 {
262   JNIEnv *env;
263   jobject obj;
264   jclass cls;
265   jmethodID method;
266   jvalue values[6];
267   generalpath *path = (generalpath *) p;
268
269   env = path->env;
270   obj = path->obj;
271   values[0].f = (jfloat)(cp1->x * path->sx + path->px);
272   values[1].f = (jfloat)(cp1->y * path->sy + path->py);
273   values[2].f = (jfloat)(cp2->x * path->sx + path->px);
274   values[3].f = (jfloat)(cp2->y * path->sy + path->py);
275   values[4].f = (jfloat)(to->x * path->sx + path->px);
276   values[5].f = (jfloat)(to->y * path->sy + path->py);
277
278   cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
279   method = (*env)->GetMethodID (env, cls, "curveTo", "(FFFFFF)V");
280   (*env)->CallVoidMethodA(env, obj, method, values );
281
282   return 0;
283 }
284
285
286 JNIEXPORT jobject JNICALL 
287 Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
288  (JNIEnv *env, jobject obj, jint glyphIndex)
289 {
290   generalpath *path;
291   jobject gp;
292   FT_Outline_Funcs ftCallbacks =
293     {
294       (FT_Outline_MoveToFunc) _moveTo,
295       (FT_Outline_LineToFunc) _lineTo,
296       (FT_Outline_ConicToFunc) _quadTo,
297       (FT_Outline_CubicToFunc) _curveTo,
298       0,
299       0
300     };
301   PangoFcFont *font;
302   FT_Face ft_face;
303   FT_Glyph glyph;
304
305   font = getFont(env, obj);
306   ft_face = pango_fc_font_lock_face( font );
307
308   g_assert (ft_face != NULL);
309
310   path = g_malloc0 (sizeof (generalpath));
311   g_assert(path != NULL);
312   path->env = env;
313
314   path->px = path->py = 0.0;
315   path->sx = 1.0/64.0;
316   path->sy = -1.0/64.0;
317
318   {  /* create a GeneralPath instance */
319     jclass cls;
320     jmethodID method;
321     
322     cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
323     method = (*env)->GetMethodID (env, cls, "<init>", "()V");
324     gp = path->obj = (*env)->NewObject (env, cls, method);
325   }
326               
327   if(FT_Load_Glyph(ft_face,
328                    (FT_UInt)(glyphIndex),
329                    FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP) != 0)
330     {
331       pango_fc_font_unlock_face( font );
332       g_free(path); 
333       return NULL;
334     }
335
336   FT_Get_Glyph( ft_face->glyph, &glyph );
337   FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
338                         &ftCallbacks, path);
339   FT_Done_Glyph( glyph );
340   
341   pango_fc_font_unlock_face( font );
342
343   g_free(path); 
344
345   return gp; 
346 }
347
348