1 /* gnu_java_awt_GdkFont.c
2 Copyright (C) 2003, 2004 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., 59 Temple Place, Suite 330, 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. */
39 #include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
41 struct state_table
*native_font_state_table
;
43 enum java_awt_font_style
{
44 java_awt_font_PLAIN
= 0,
45 java_awt_font_BOLD
= 1,
46 java_awt_font_ITALIC
= 2
49 enum java_awt_font_baseline
{
50 java_awt_font_ROMAN_BASELINE
= 0,
51 java_awt_font_CENTER_BASELINE
= 1,
52 java_awt_font_HANGING_BASELINE
= 2
55 static jmethodID glyphVector_ctor
;
56 static jclass glyphVector_class
;
57 static PangoAttrList
*attrs
= NULL
;
59 JNIEXPORT
void JNICALL
60 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState
61 (JNIEnv
*env
, jclass clazz
)
63 NSA_FONT_INIT (env
, clazz
);
65 glyphVector_class
= (*env
)->FindClass
66 (env
, "gnu/java/awt/peer/gtk/GdkGlyphVector");
68 glyphVector_ctor
= (*env
)->GetMethodID
69 (env
, glyphVector_class
, "<init>",
70 "([D[ILjava/awt/Font;Ljava/awt/font/FontRenderContext;)V");
73 JNIEXPORT
void JNICALL
74 Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
75 (JNIEnv
*env
, jobject self
)
77 struct peerfont
*pfont
= NULL
;
79 g_assert (self
!= NULL
);
80 pfont
= (struct peerfont
*) g_malloc0 (sizeof (struct peerfont
));
81 g_assert (pfont
!= NULL
);
82 NSA_SET_FONT_PTR (env
, self
, pfont
);
87 JNIEXPORT
void JNICALL
88 Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
89 (JNIEnv
*env
, jobject self
)
91 struct peerfont
*pfont
= NULL
;
94 pfont
= (struct peerfont
*)NSA_DEL_FONT_PTR (env
, self
);
95 g_assert (pfont
!= NULL
);
96 if (pfont
->layout
!= NULL
)
97 g_object_unref (pfont
->font
);
98 if (pfont
->font
!= NULL
)
99 g_object_unref (pfont
->font
);
100 if (pfont
->ctx
!= NULL
)
101 g_object_unref (pfont
->ctx
);
102 if (pfont
->desc
!= NULL
)
103 pango_font_description_free (pfont
->desc
);
105 gdk_threads_leave ();
109 JNIEXPORT jobject JNICALL
110 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
111 (JNIEnv
*env
, jobject self
,
114 jobject fontRenderContext
)
116 struct peerfont
*pfont
= NULL
;
117 GList
*items
= NULL
, *i
= NULL
;
120 double *native_extents
;
122 jintArray java_codes
= NULL
;
123 jdoubleArray java_extents
= NULL
;
125 gdk_threads_enter ();
127 pfont
= (struct peerfont
*)NSA_GET_FONT_PTR (env
, self
);
128 g_assert (pfont
!= NULL
);
130 len
= (*gdk_env())->GetStringUTFLength (env
, chars
);
131 str
= (gchar
*)(*env
)->GetStringUTFChars (env
, chars
, NULL
);
132 g_assert (str
!= NULL
);
135 attrs
= pango_attr_list_new ();
137 if (len
> 0 && str
[len
-1] == '\0')
140 items
= pango_itemize (pfont
->ctx
, str
, 0, len
, attrs
, NULL
);
142 i
= g_list_first (items
);
146 java_extents
= (*env
)->NewDoubleArray (env
, 0);
147 java_codes
= (*env
)->NewIntArray (env
, 0);
151 PangoGlyphString
*glyphs
;
152 PangoItem
*item
= (PangoItem
*)i
->data
;
154 pango_context_set_font_description (pfont
->ctx
, pfont
->desc
);
155 pango_context_set_language (pfont
->ctx
, gtk_get_default_language());
156 pango_context_load_font (pfont
->ctx
, pfont
->desc
);
158 glyphs
= pango_glyph_string_new ();
159 g_assert (glyphs
!= NULL
);
161 pango_shape (str
+ item
->offset
, item
->length
,
162 &(item
->analysis
), glyphs
);
164 if (glyphs
->num_glyphs
> 0)
167 double scale
= ((double) PANGO_SCALE
);
169 java_extents
= (*env
)->NewDoubleArray (env
, glyphs
->num_glyphs
* NUM_GLYPH_METRICS
);
170 java_codes
= (*env
)->NewIntArray (env
, glyphs
->num_glyphs
);
171 native_extents
= (*env
)->GetDoubleArrayElements (env
, java_extents
, NULL
);
172 native_codes
= (*env
)->GetIntArrayElements (env
, java_codes
, NULL
);
174 for (j
= 0; j
< glyphs
->num_glyphs
; ++j
)
177 PangoRectangle logical
;
178 PangoGlyphGeometry
*geom
= &glyphs
->glyphs
[j
].geometry
;
180 pango_font_get_glyph_extents (pfont
->font
,
181 glyphs
->glyphs
[j
].glyph
,
184 native_codes
[j
] = glyphs
->glyphs
[j
].glyph
;
186 native_extents
[ GLYPH_LOG_X(j
) ] = (logical
.x
) / scale
;
187 native_extents
[ GLYPH_LOG_Y(j
) ] = (- logical
.y
) / scale
;
188 native_extents
[ GLYPH_LOG_WIDTH(j
) ] = (logical
.width
) / scale
;
189 native_extents
[ GLYPH_LOG_HEIGHT(j
) ] = (logical
.height
) / scale
;
191 native_extents
[ GLYPH_INK_X(j
) ] = (ink
.x
) / scale
;
192 native_extents
[ GLYPH_INK_Y(j
) ] = (- ink
.y
) / scale
;
193 native_extents
[ GLYPH_INK_WIDTH(j
) ] = (ink
.width
) / scale
;
194 native_extents
[ GLYPH_INK_HEIGHT(j
) ] = (ink
.height
) / scale
;
196 native_extents
[ GLYPH_POS_X(j
) ] = (x
+ geom
->x_offset
) / scale
;
197 native_extents
[ GLYPH_POS_Y(j
) ] = ( - geom
->y_offset
) / scale
;
201 (*env
)->ReleaseDoubleArrayElements (env
, java_extents
, native_extents
, 0);
202 (*env
)->ReleaseIntArrayElements (env
, java_codes
, native_codes
, 0);
205 pango_glyph_string_free (glyphs
);
208 (*env
)->ReleaseStringUTFChars (env
, chars
, str
);
210 for (i
= g_list_first (items
); i
!= NULL
; i
= g_list_next (i
))
215 gdk_threads_leave ();
217 return (*env
)->NewObject (env
,
220 java_extents
, java_codes
,
221 font
, fontRenderContext
);
224 JNIEXPORT
void JNICALL
225 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
226 (JNIEnv
*env
, jobject java_font
, jdoubleArray java_metrics
)
228 struct peerfont
*pfont
= NULL
;
229 jdouble
*native_metrics
= NULL
;
230 PangoFontMetrics
*pango_metrics
;
234 pfont
= (struct peerfont
*) NSA_GET_FONT_PTR (env
, java_font
);
235 g_assert (pfont
!= NULL
);
238 = pango_context_get_metrics (pfont
->ctx
, pfont
->desc
,
239 gtk_get_default_language ());
242 = (*env
)->GetDoubleArrayElements (env
, java_metrics
, NULL
);
244 g_assert (native_metrics
!= NULL
);
246 native_metrics
[FONT_METRICS_ASCENT
]
247 = PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics
));
249 native_metrics
[FONT_METRICS_MAX_ASCENT
]
250 = native_metrics
[FONT_METRICS_ASCENT
];
252 native_metrics
[FONT_METRICS_DESCENT
]
253 = PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics
));
255 if (native_metrics
[FONT_METRICS_DESCENT
] < 0)
256 native_metrics
[FONT_METRICS_DESCENT
]
257 = - native_metrics
[FONT_METRICS_DESCENT
];
259 native_metrics
[FONT_METRICS_MAX_DESCENT
]
260 = native_metrics
[FONT_METRICS_DESCENT
];
262 native_metrics
[FONT_METRICS_MAX_ADVANCE
]
263 = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width
266 (*env
)->ReleaseDoubleArrayElements (env
,
270 pango_font_metrics_unref (pango_metrics
);
275 JNIEXPORT
void JNICALL
276 Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
277 (JNIEnv
*env
, jobject java_font
, jstring str
, jdoubleArray java_metrics
)
279 struct peerfont
*pfont
= NULL
;
280 const char *cstr
= NULL
;
281 jdouble
*native_metrics
= NULL
;
286 pfont
= (struct peerfont
*)NSA_GET_FONT_PTR (env
, java_font
);
287 g_assert (pfont
!= NULL
);
289 cstr
= (*env
)->GetStringUTFChars (env
, str
, NULL
);
290 g_assert(cstr
!= NULL
);
292 pango_layout_set_text (pfont
->layout
, cstr
, -1);
293 pango_layout_get_extents (pfont
->layout
, NULL
, &log
);
295 (*env
)->ReleaseStringUTFChars (env
, str
, cstr
);
296 pango_layout_set_text (pfont
->layout
, "", -1);
298 native_metrics
= (*env
)->GetDoubleArrayElements (env
, java_metrics
, NULL
);
299 g_assert (native_metrics
!= NULL
);
301 native_metrics
[TEXT_METRICS_X_BEARING
]
302 = PANGO_PIXELS( ((double)log
.x
) );
304 native_metrics
[TEXT_METRICS_Y_BEARING
]
305 = PANGO_PIXELS( ((double)log
.y
) );
307 native_metrics
[TEXT_METRICS_WIDTH
]
308 = PANGO_PIXELS( ((double)log
.width
) );
310 native_metrics
[TEXT_METRICS_HEIGHT
]
311 = PANGO_PIXELS( ((double)log
.height
) );
313 native_metrics
[TEXT_METRICS_X_ADVANCE
]
314 = PANGO_PIXELS( ((double) (log
.x
+ log
.width
)) );
316 native_metrics
[TEXT_METRICS_Y_ADVANCE
]
317 = PANGO_PIXELS( ((double) (log
.y
+ log
.height
)) );
319 (*env
)->ReleaseDoubleArrayElements (env
, java_metrics
, native_metrics
, 0);
325 JNIEXPORT
void JNICALL
326 Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
327 (JNIEnv
*env
, jobject self
, jstring family_name_str
, jint style_int
, jint size
, jboolean useGraphics2D
)
329 struct peerfont
*pfont
= NULL
;
330 char const *family_name
= NULL
;
331 enum java_awt_font_style style
;
332 PangoFT2FontMap
*ft2_map
;
334 gdk_threads_enter ();
335 style
= (enum java_awt_font_style
) style_int
;
337 g_assert (self
!= NULL
);
338 pfont
= (struct peerfont
*)NSA_GET_FONT_PTR (env
, self
);
339 g_assert (pfont
!= NULL
);
341 if (pfont
->ctx
!= NULL
)
342 g_object_unref (pfont
->ctx
);
343 if (pfont
->font
!= NULL
)
344 g_object_unref (pfont
->font
);
345 if (pfont
->desc
!= NULL
)
346 pango_font_description_free (pfont
->desc
);
348 pfont
->desc
= pango_font_description_new ();
349 g_assert (pfont
->desc
!= NULL
);
351 family_name
= (*env
)->GetStringUTFChars(env
, family_name_str
, 0);
352 g_assert (family_name
!= NULL
);
353 pango_font_description_set_family (pfont
->desc
, family_name
);
354 (*env
)->ReleaseStringUTFChars(env
, family_name_str
, family_name
);
357 if (style
& java_awt_font_BOLD
)
358 pango_font_description_set_weight (pfont
->desc
, PANGO_WEIGHT_BOLD
);
360 if (style
& java_awt_font_ITALIC
)
361 pango_font_description_set_style (pfont
->desc
, PANGO_STYLE_ITALIC
);
365 pango_font_description_set_size (pfont
->desc
, size
* PANGO_SCALE
);
366 if (pfont
->ctx
== NULL
)
368 ft2_map
= PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
369 pfont
->ctx
= pango_ft2_font_map_create_context (ft2_map
);
374 /* GDK uses a slightly different DPI setting. */
375 pango_font_description_set_size (pfont
->desc
,
376 size
* dpi_conversion_factor
);
377 if (pfont
->ctx
== NULL
)
378 pfont
->ctx
= gdk_pango_context_get();
381 g_assert (pfont
->ctx
!= NULL
);
383 if (pfont
->font
!= NULL
)
385 g_object_unref (pfont
->font
);
389 pango_context_set_font_description (pfont
->ctx
, pfont
->desc
);
390 pango_context_set_language (pfont
->ctx
, gtk_get_default_language());
391 pfont
->font
= pango_context_load_font (pfont
->ctx
, pfont
->desc
);
392 g_assert (pfont
->font
!= NULL
);
394 if (pfont
->layout
== NULL
)
395 pfont
->layout
= pango_layout_new (pfont
->ctx
);
396 g_assert (pfont
->layout
!= NULL
);
398 gdk_threads_leave ();