diff options
Diffstat (limited to 'libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c')
-rw-r--r-- | libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c | 250 |
1 files changed, 232 insertions, 18 deletions
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c index d9926532bfb..7a8a2ceefd8 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c @@ -40,23 +40,6 @@ struct state_table *native_font_state_table; -/* -rough sketch of the mapping between java and -pango text objects: - - Font <-> - PangoFont - - PangoFontDescription - - PangoContext - - PangoLayout (for rendering and measuring) - - GlyphVector <-> - GList of PangoGlyphItem - - PangoFontDescription - - PangoContext - - FontRenderContext <-> stays in plain java - -*/ - enum java_awt_font_style { java_awt_font_PLAIN = 0, java_awt_font_BOLD = 1, @@ -69,11 +52,22 @@ enum java_awt_font_baseline { 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 @@ -111,6 +105,223 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose 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) @@ -142,7 +353,6 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont pango_font_description_set_family (pfont->desc, family_name); (*env)->ReleaseStringUTFChars(env, family_name_str, family_name); - pango_font_description_set_size (pfont->desc, size * dpi_conversion_factor); if (style & java_awt_font_BOLD) pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD); @@ -152,6 +362,7 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont 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 ()); @@ -160,6 +371,9 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont } else { + /* GDK uses a slightly different DPI setting. */ + pango_font_description_set_size (pfont->desc, + size * dpi_conversion_factor); if (pfont->ctx == NULL) pfont->ctx = gdk_pango_context_get(); } |