gnu_java_awt_peer_gtk_GdkFontPeer.c [plain text]
#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
struct state_table *native_font_state_table;
enum java_awt_font_style {
java_awt_font_PLAIN = 0,
java_awt_font_BOLD = 1,
java_awt_font_ITALIC = 2
};
enum java_awt_font_baseline {
java_awt_font_ROMAN_BASELINE = 0,
java_awt_font_CENTER_BASELINE = 1,
java_awt_font_HANGING_BASELINE = 2
};
static jmethodID glyphVector_ctor;
static jclass glyphVector_class;
static PangoAttrList *attrs = NULL;
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState
(JNIEnv *env, jclass clazz)
{
NSA_FONT_INIT (env, clazz);
glyphVector_class = (*env)->FindClass
(env, "gnu/java/awt/peer/gtk/GdkGlyphVector");
glyphVector_ctor = (*env)->GetMethodID
(env, glyphVector_class, "<init>",
"([D[ILjava/awt/Font;Ljava/awt/font/FontRenderContext;)V");
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
(JNIEnv *env, jobject self)
{
struct peerfont *pfont = NULL;
gdk_threads_enter ();
g_assert (self != NULL);
pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
g_assert (pfont != NULL);
NSA_SET_FONT_PTR (env, self, pfont);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
(JNIEnv *env, jobject self)
{
struct peerfont *pfont = NULL;
gdk_threads_enter ();
pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self);
g_assert (pfont != NULL);
if (pfont->layout != NULL)
g_object_unref (pfont->font);
if (pfont->font != NULL)
g_object_unref (pfont->font);
if (pfont->ctx != NULL)
g_object_unref (pfont->ctx);
if (pfont->desc != NULL)
pango_font_description_free (pfont->desc);
g_free (pfont);
gdk_threads_leave ();
}
JNIEXPORT jobject JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
(JNIEnv *env, jobject self,
jstring chars,
jobject font,
jobject fontRenderContext)
{
struct peerfont *pfont = NULL;
GList *items = NULL, *i = NULL;
gchar *str = NULL;
int len, j;
double *native_extents;
int *native_codes;
jintArray java_codes = NULL;
jdoubleArray java_extents = NULL;
gdk_threads_enter ();
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
g_assert (pfont != NULL);
len = (*gdk_env())->GetStringUTFLength (env, chars);
str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
g_assert (str != NULL);
if (attrs == NULL)
attrs = pango_attr_list_new ();
if (len > 0 && str[len-1] == '\0')
len--;
items = pango_itemize (pfont->ctx, str, 0, len, attrs, NULL);
i = g_list_first (items);
if (i == NULL)
{
java_extents = (*env)->NewDoubleArray (env, 0);
java_codes = (*env)->NewIntArray (env, 0);
}
else
{
PangoGlyphString *glyphs;
PangoItem *item = (PangoItem *)i->data;
pango_context_set_font_description (pfont->ctx, pfont->desc);
pango_context_set_language (pfont->ctx, gtk_get_default_language());
pango_context_load_font (pfont->ctx, pfont->desc);
glyphs = pango_glyph_string_new ();
g_assert (glyphs != NULL);
pango_shape (str + item->offset, item->length,
&(item->analysis), glyphs);
if (glyphs->num_glyphs > 0)
{
int x = 0;
double scale = ((double) PANGO_SCALE);
java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS);
java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs);
native_extents = (*env)->GetDoubleArrayElements (env, java_extents, NULL);
native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
for (j = 0; j < glyphs->num_glyphs; ++j)
{
PangoRectangle ink;
PangoRectangle logical;
PangoGlyphGeometry *geom = &glyphs->glyphs[j].geometry;
pango_font_get_glyph_extents (pfont->font,
glyphs->glyphs[j].glyph,
&ink, &logical);
native_codes[j] = glyphs->glyphs[j].glyph;
native_extents[ GLYPH_LOG_X(j) ] = (logical.x) / scale;
native_extents[ GLYPH_LOG_Y(j) ] = (- logical.y) / scale;
native_extents[ GLYPH_LOG_WIDTH(j) ] = (logical.width) / scale;
native_extents[ GLYPH_LOG_HEIGHT(j) ] = (logical.height) / scale;
native_extents[ GLYPH_INK_X(j) ] = (ink.x) / scale;
native_extents[ GLYPH_INK_Y(j) ] = (- ink.y) / scale;
native_extents[ GLYPH_INK_WIDTH(j) ] = (ink.width) / scale;
native_extents[ GLYPH_INK_HEIGHT(j) ] = (ink.height) / scale;
native_extents[ GLYPH_POS_X(j) ] = (x + geom->x_offset) / scale;
native_extents[ GLYPH_POS_Y(j) ] = ( - geom->y_offset) / scale;
x += geom->width;
}
(*env)->ReleaseDoubleArrayElements (env, java_extents, native_extents, 0);
(*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
}
pango_glyph_string_free (glyphs);
}
(*env)->ReleaseStringUTFChars (env, chars, str);
for (i = g_list_first (items); i != NULL; i = g_list_next (i))
g_free (i->data);
g_list_free (items);
gdk_threads_leave ();
return (*env)->NewObject (env,
glyphVector_class,
glyphVector_ctor,
java_extents, java_codes,
font, fontRenderContext);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
(JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
{
struct peerfont *pfont = NULL;
jdouble *native_metrics = NULL;
PangoFontMetrics *pango_metrics;
gdk_threads_enter();
pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
g_assert (pfont != NULL);
pango_metrics
= pango_context_get_metrics (pfont->ctx, pfont->desc,
gtk_get_default_language ());
native_metrics
= (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
g_assert (native_metrics != NULL);
native_metrics[FONT_METRICS_ASCENT]
= PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics));
native_metrics[FONT_METRICS_MAX_ASCENT]
= native_metrics[FONT_METRICS_ASCENT];
native_metrics[FONT_METRICS_DESCENT]
= PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics));
if (native_metrics[FONT_METRICS_DESCENT] < 0)
native_metrics[FONT_METRICS_DESCENT]
= - native_metrics[FONT_METRICS_DESCENT];
native_metrics[FONT_METRICS_MAX_DESCENT]
= native_metrics[FONT_METRICS_DESCENT];
native_metrics[FONT_METRICS_MAX_ADVANCE]
= PANGO_PIXELS (pango_font_metrics_get_approximate_char_width
(pango_metrics));
(*env)->ReleaseDoubleArrayElements (env,
java_metrics,
native_metrics, 0);
pango_font_metrics_unref (pango_metrics);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
(JNIEnv *env, jobject java_font, jstring str, jdoubleArray java_metrics)
{
struct peerfont *pfont = NULL;
const char *cstr = NULL;
jdouble *native_metrics = NULL;
PangoRectangle log;
gdk_threads_enter();
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font);
g_assert (pfont != NULL);
cstr = (*env)->GetStringUTFChars (env, str, NULL);
g_assert(cstr != NULL);
pango_layout_set_text (pfont->layout, cstr, -1);
pango_layout_get_extents (pfont->layout, NULL, &log);
(*env)->ReleaseStringUTFChars (env, str, cstr);
pango_layout_set_text (pfont->layout, "", -1);
native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
g_assert (native_metrics != NULL);
native_metrics[TEXT_METRICS_X_BEARING]
= PANGO_PIXELS( ((double)log.x) );
native_metrics[TEXT_METRICS_Y_BEARING]
= PANGO_PIXELS( ((double)log.y) );
native_metrics[TEXT_METRICS_WIDTH]
= PANGO_PIXELS( ((double)log.width) );
native_metrics[TEXT_METRICS_HEIGHT]
= PANGO_PIXELS( ((double)log.height) );
native_metrics[TEXT_METRICS_X_ADVANCE]
= PANGO_PIXELS( ((double) (log.x + log.width)) );
native_metrics[TEXT_METRICS_Y_ADVANCE]
= PANGO_PIXELS( ((double) (log.y + log.height)) );
(*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
(JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D)
{
struct peerfont *pfont = NULL;
char const *family_name = NULL;
enum java_awt_font_style style;
PangoFT2FontMap *ft2_map;
gdk_threads_enter ();
style = (enum java_awt_font_style) style_int;
g_assert (self != NULL);
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
g_assert (pfont != NULL);
if (pfont->ctx != NULL)
g_object_unref (pfont->ctx);
if (pfont->font != NULL)
g_object_unref (pfont->font);
if (pfont->desc != NULL)
pango_font_description_free (pfont->desc);
pfont->desc = pango_font_description_new ();
g_assert (pfont->desc != NULL);
family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
g_assert (family_name != NULL);
pango_font_description_set_family (pfont->desc, family_name);
(*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
if (style & java_awt_font_BOLD)
pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
if (style & java_awt_font_ITALIC)
pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
if (useGraphics2D)
{
pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
if (pfont->ctx == NULL)
{
ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
pfont->ctx = pango_ft2_font_map_create_context (ft2_map);
}
}
else
{
pango_font_description_set_size (pfont->desc,
size * dpi_conversion_factor);
if (pfont->ctx == NULL)
pfont->ctx = gdk_pango_context_get();
}
g_assert (pfont->ctx != NULL);
if (pfont->font != NULL)
{
g_object_unref (pfont->font);
pfont->font = NULL;
}
pango_context_set_font_description (pfont->ctx, pfont->desc);
pango_context_set_language (pfont->ctx, gtk_get_default_language());
pfont->font = pango_context_load_font (pfont->ctx, pfont->desc);
g_assert (pfont->font != NULL);
if (pfont->layout == NULL)
pfont->layout = pango_layout_new (pfont->ctx);
g_assert (pfont->layout != NULL);
gdk_threads_leave ();
}