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)
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. */
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"
49 #include "gnu_java_awt_peer_gtk_GdkTextLayout.h"
51 struct state_table
*cp_gtk_native_text_layout_state_table
;
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
;
78 g_assert(self
!= NULL
);
79 tl
= g_malloc0 (sizeof (struct textlayout
));
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
);
88 JNIEXPORT
void JNICALL
89 Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
90 (JNIEnv
*env
, jobject self
, jstring text
)
92 struct textlayout
*tl
;
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
;
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
);
207 gdk_threads_leave ();
210 /* GetOutline code follows ****************************/
211 /********* Freetype callback functions *****************************/
213 static int _moveTo( FT_Vector
* to
,
221 generalpath
*path
= (generalpath
*) p
;
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
);
236 static int _lineTo( FT_Vector
* to
,
244 generalpath
*path
= (generalpath
*) p
;
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
);
258 static int _quadTo( FT_Vector
* cp
,
267 generalpath
*path
= (generalpath
*) p
;
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
);
283 static int _curveTo( FT_Vector
* cp1
,
293 generalpath
*path
= (generalpath
*) p
;
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
);
312 JNIEXPORT jobject JNICALL
313 Java_gnu_java_awt_peer_gtk_GdkTextLayout_getOutline
314 (JNIEnv
*env
, jobject obj
, jobject transform
)
316 struct textlayout
*tl
;
320 PangoLayoutLine
*current_line
;
321 FT_Outline_Funcs ftCallbacks
=
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
);
342 /* Scaling factors */
343 path
->sx
= PANGO_SCALE
/65536.0;
344 path
->sy
= -PANGO_SCALE
/65536.0;
346 { /* create a GeneralPath instance */
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
,
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
;
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
++)
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
),
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
));
410 gdk_threads_leave ();
412 if (transform
!= NULL
)
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
);