Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GdkTextLayout.c
blobedce3917d68032e440d880f51aaaf4b733aecbb3
1 /* gnu_java_awt_GdkTextLayout.c
2 Copyright (C) 2004, 2005 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)
9 any later version.
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
19 02110-1301 USA.
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.
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. */
39 #include <jni.h>
40 #include <gtk/gtk.h>
41 #include <string.h>
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>
47 #include "native_state.h"
48 #include "gdkfont.h"
49 #include "gnu_java_awt_peer_gtk_GdkTextLayout.h"
51 struct state_table *cp_gtk_native_text_layout_state_table;
53 typedef struct gp
55 JNIEnv *env;
56 jobject obj;
57 double px;
58 double py;
59 double sx;
60 double sy;
61 } generalpath ;
63 JNIEXPORT void JNICALL
64 Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState
65 (JNIEnv *env, jclass clazz)
67 NSA_TEXT_LAYOUT_INIT (env, clazz);
70 JNIEXPORT void JNICALL
71 Java_gnu_java_awt_peer_gtk_GdkTextLayout_initState
72 (JNIEnv *env, jobject self)
74 struct textlayout *tl;
76 gdk_threads_enter ();
78 g_assert(self != NULL);
79 tl = g_malloc0 (sizeof (struct textlayout));
80 g_assert(tl != NULL);
81 tl->pango_layout = pango_layout_new(gdk_pango_context_get());
82 g_assert(tl->pango_layout != NULL);
83 NSA_SET_TEXT_LAYOUT_PTR (env, self, tl);
85 gdk_threads_leave ();
88 JNIEXPORT void JNICALL
89 Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
90 (JNIEnv *env, jobject self, jstring text)
92 struct textlayout *tl;
93 gchar *str = NULL;
94 gint len = 0;
96 gdk_threads_enter ();
98 g_assert(self != NULL);
99 g_assert(text != NULL);
101 tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
102 g_assert(tl != NULL);
103 g_assert(tl->pango_layout != NULL);
105 len = (*env)->GetStringUTFLength (env, text);
106 str = (gchar *)(*env)->GetStringUTFChars (env, text, NULL);
107 g_assert (str != NULL);
109 pango_layout_set_text (tl->pango_layout, text, len);
111 (*env)->ReleaseStringUTFChars (env, text, str);
113 gdk_threads_leave ();
116 JNIEXPORT void JNICALL
117 Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos
118 (JNIEnv *env, jobject self, jint idx, jdoubleArray javaPos)
120 struct textlayout *tl;
121 PangoRectangle pangoPos;
122 jdouble *nativePos;
124 gdk_threads_enter ();
126 g_assert(self != NULL);
127 g_assert(javaPos != NULL);
129 tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
130 g_assert(tl != NULL);
131 g_assert(tl->pango_layout != NULL);
133 g_assert((*env)->GetArrayLength (env, javaPos) == 4);
135 nativePos = (*env)->GetDoubleArrayElements (env, javaPos, NULL);
137 pango_layout_index_to_pos (tl->pango_layout, idx, &pangoPos);
139 nativePos[0] = (jdouble) pangoPos.x;
140 nativePos[1] = (jdouble) pangoPos.y;
141 nativePos[2] = (jdouble) pangoPos.width;
142 nativePos[3] = (jdouble) pangoPos.height;
144 (*env)->ReleaseDoubleArrayElements (env, javaPos, nativePos, 0);
146 gdk_threads_leave ();
149 JNIEXPORT void JNICALL
150 Java_gnu_java_awt_peer_gtk_GdkTextLayout_getExtents
151 (JNIEnv *env, jobject self, jdoubleArray javaInkExtents, jdoubleArray javaLogExtents)
153 struct textlayout *tl;
154 PangoRectangle pangoInkExtents, pangoLogExtents;
155 jdouble *nativeInkExtents, *nativeLogExtents;
157 gdk_threads_enter ();
159 g_assert(self != NULL);
160 g_assert(javaInkExtents != NULL);
161 g_assert(javaLogExtents != NULL);
163 tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
164 g_assert(tl != NULL);
165 g_assert(tl->pango_layout != NULL);
167 g_assert((*env)->GetArrayLength (env, javaInkExtents) == 4);
168 g_assert((*env)->GetArrayLength (env, javaLogExtents) == 4);
170 nativeInkExtents = (*env)->GetDoubleArrayElements (env, javaInkExtents, NULL);
171 nativeLogExtents = (*env)->GetDoubleArrayElements (env, javaLogExtents, NULL);
173 pango_layout_get_extents (tl->pango_layout,
174 &pangoInkExtents, &pangoLogExtents);
176 nativeInkExtents[0] = (jdouble) pangoInkExtents.x;
177 nativeInkExtents[1] = (jdouble) pangoInkExtents.y;
178 nativeInkExtents[2] = (jdouble) pangoInkExtents.width;
179 nativeInkExtents[3] = (jdouble) pangoInkExtents.height;
181 nativeLogExtents[0] = (jdouble) pangoLogExtents.x;
182 nativeLogExtents[1] = (jdouble) pangoLogExtents.y;
183 nativeLogExtents[2] = (jdouble) pangoLogExtents.width;
184 nativeLogExtents[3] = (jdouble) pangoLogExtents.height;
186 (*env)->ReleaseDoubleArrayElements (env, javaInkExtents, nativeInkExtents, 0);
187 (*env)->ReleaseDoubleArrayElements (env, javaLogExtents, nativeLogExtents, 0);
189 gdk_threads_leave ();
192 JNIEXPORT void JNICALL
193 Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose
194 (JNIEnv *env, jobject self)
196 struct textlayout *tl;
198 gdk_threads_enter ();
200 g_assert(self != NULL);
201 tl = (struct textlayout *) NSA_DEL_TEXT_LAYOUT_PTR (env, self);
202 g_assert(tl != NULL);
203 if (tl->pango_layout != NULL)
204 g_object_unref (tl->pango_layout);
205 g_free(tl);
207 gdk_threads_leave ();
210 /* GetOutline code follows ****************************/
211 /********* Freetype callback functions *****************************/
213 static int _moveTo( FT_Vector* to,
214 void *p)
216 JNIEnv *env;
217 jobject obj;
218 jclass cls;
219 jmethodID method;
220 jvalue values[2];
221 generalpath *path = (generalpath *) p;
223 env = path->env;
224 obj = path->obj;
226 values[0].f = (jfloat)(to->x * path->sx + path->px);
227 values[1].f = (jfloat)(to->y * path->sy + path->py);
229 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
230 method = (*env)->GetMethodID (env, cls, "moveTo", "(FF)V");
231 (*env)->CallVoidMethodA(env, obj, method, values );
233 return 0;
236 static int _lineTo( FT_Vector* to,
237 void *p)
239 JNIEnv *env;
240 jobject obj;
241 jclass cls;
242 jmethodID method;
243 jvalue values[2];
244 generalpath *path = (generalpath *) p;
246 env = path->env;
247 obj = path->obj;
248 values[0].f = (jfloat)(to->x * path->sx + path->px);
249 values[1].f = (jfloat)(to->y * path->sy + path->py);
251 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
252 method = (*env)->GetMethodID (env, cls, "lineTo", "(FF)V");
253 (*env)->CallVoidMethodA(env, obj, method, values );
255 return 0;
258 static int _quadTo( FT_Vector* cp,
259 FT_Vector* to,
260 void *p)
262 JNIEnv *env;
263 jobject obj;
264 jclass cls;
265 jmethodID method;
266 jvalue values[4];
267 generalpath *path = (generalpath *) p;
269 env = path->env;
270 obj = path->obj;
271 values[0].f = (jfloat)(cp->x * path->sx + path->px);
272 values[1].f = (jfloat)(cp->y * path->sy + path->py);
273 values[2].f = (jfloat)(to->x * path->sx + path->px);
274 values[3].f = (jfloat)(to->y * path->sy + path->py);
276 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
277 method = (*env)->GetMethodID (env, cls, "quadTo", "(FFFF)V");
278 (*env)->CallVoidMethodA(env, obj, method, values );
280 return 0;
283 static int _curveTo( FT_Vector* cp1,
284 FT_Vector* cp2,
285 FT_Vector* to,
286 void *p)
288 JNIEnv *env;
289 jobject obj;
290 jclass cls;
291 jmethodID method;
292 jvalue values[6];
293 generalpath *path = (generalpath *) p;
295 env = path->env;
296 obj = path->obj;
297 values[0].f = (jfloat)(cp1->x * path->sx + path->px);
298 values[1].f = (jfloat)(cp1->y * path->sy + path->py);
299 values[2].f = (jfloat)(cp2->x * path->sx + path->px);
300 values[3].f = (jfloat)(cp2->y * path->sy + path->py);
301 values[4].f = (jfloat)(to->x * path->sx + path->px);
302 values[5].f = (jfloat)(to->y * path->sy + path->py);
304 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
305 method = (*env)->GetMethodID (env, cls, "curveTo", "(FFFFFF)V");
306 (*env)->CallVoidMethodA(env, obj, method, values );
308 return 0;
312 JNIEXPORT jobject JNICALL
313 Java_gnu_java_awt_peer_gtk_GdkTextLayout_getOutline
314 (JNIEnv *env, jobject obj, jobject transform)
316 struct textlayout *tl;
317 generalpath *path;
318 jobject gp;
319 GSList *current_run;
320 PangoLayoutLine *current_line;
321 FT_Outline_Funcs ftCallbacks =
323 _moveTo,
324 _lineTo,
325 _quadTo,
326 _curveTo,
330 PangoLayoutIter* layoutIterator;
332 gdk_threads_enter ();
334 tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, obj);
335 g_assert(tl != NULL);
336 g_assert(tl->pango_layout != NULL);
338 path = g_malloc0 (sizeof (generalpath));
339 g_assert(path != NULL);
340 path->env = env;
342 /* Scaling factors */
343 path->sx = PANGO_SCALE/65536.0;
344 path->sy = -PANGO_SCALE/65536.0;
346 { /* create a GeneralPath instance */
347 jclass cls;
348 jmethodID method;
350 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
351 method = (*env)->GetMethodID (env, cls, "<init>", "()V");
352 gp = path->obj = (*env)->NewObject (env, cls, method);
355 layoutIterator = pango_layout_get_iter (tl->pango_layout);
356 g_assert (layoutIterator != NULL);
358 if (pango_layout_iter_get_line (layoutIterator))
361 PangoRectangle line_logical_rect;
362 current_line = pango_layout_iter_get_line (layoutIterator);
363 pango_layout_iter_get_line_extents (layoutIterator,
364 NULL,
365 &line_logical_rect);
367 path->px = line_logical_rect.x/(double)PANGO_SCALE;
368 path->py = line_logical_rect.y/(double)PANGO_SCALE;
370 current_run = current_line->runs;
371 while (current_run)
373 FT_Face ft_face;
374 int index;
375 PangoGlyphItem *run = current_run->data;
376 PangoGlyphString *glyphs = run->glyphs;
378 PangoAnalysis *analysis = &run->item->analysis;
379 g_assert (analysis != NULL);
380 g_assert (analysis->font != NULL);
382 ft_face = pango_fc_font_lock_face ((PangoFcFont *)analysis->font);
383 g_assert (ft_face != NULL);
385 for (index = 0; index < glyphs->num_glyphs; index++)
387 FT_Glyph glyph;
388 FT_Error fterror;
389 PangoGlyphGeometry pgg = glyphs->glyphs[index].geometry;
391 fterror = FT_Load_Glyph(ft_face,
392 (FT_UInt)(glyphs->glyphs[index].glyph),
393 FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP);
394 g_assert(fterror == 0);
396 FT_Get_Glyph (ft_face->glyph, &glyph);
397 FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
398 &ftCallbacks, path);
399 FT_Done_Glyph (glyph);
401 path->px += pgg.width/(double)PANGO_SCALE;
404 pango_fc_font_unlock_face ((PangoFcFont *)analysis->font);
405 current_run = current_run->next;
407 } while (pango_layout_iter_next_line (layoutIterator));
409 g_free(path);
410 gdk_threads_leave ();
412 if (transform != NULL)
414 jclass cls;
415 jmethodID method;
417 cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
418 method = (*env)->GetMethodID (env, cls, "transform",
419 "(Ljava/awt/geom/AffineTransform;)V");
420 (*env)->CallVoidMethod(env, gp, method, transform );
423 return gp;