diff --git a/src/api-impl-jni/generated_headers/android_text_Layout.h b/src/api-impl-jni/generated_headers/android_text_Layout.h index 40dbf67a..ce6c339b 100644 --- a/src/api-impl-jni/generated_headers/android_text_Layout.h +++ b/src/api-impl-jni/generated_headers/android_text_Layout.h @@ -143,6 +143,14 @@ JNIEXPORT jint JNICALL Java_android_text_Layout_native_1get_1ellipsis_1count JNIEXPORT void JNICALL Java_android_text_Layout_native_1draw (JNIEnv *, jobject, jlong, jlong, jlong); +/* + * Class: android_text_Layout + * Method: native_draw_custom_canvas + * Signature: (JLandroid/graphics/Canvas;Landroid/graphics/Paint;)V + */ +JNIEXPORT void JNICALL Java_android_text_Layout_native_1draw_1custom_1canvas + (JNIEnv *, jobject, jlong, jobject, jobject); + #ifdef __cplusplus } #endif diff --git a/src/api-impl-jni/graphics/android_graphics_GskCanvas.c b/src/api-impl-jni/graphics/android_graphics_GskCanvas.c index f1b20122..5ecc97a3 100644 --- a/src/api-impl-jni/graphics/android_graphics_GskCanvas.c +++ b/src/api-impl-jni/graphics/android_graphics_GskCanvas.c @@ -104,7 +104,7 @@ JNIEXPORT void JNICALL Java_android_graphics_GskCanvas_native_1drawText(JNIEnv * (*env)->ReleaseStringUTFChars(env, text, str); PangoRectangle rect; pango_layout_get_pixel_extents(layout, NULL, &rect); - y -= rect.height; + y -= (float)pango_layout_get_baseline(layout) / PANGO_SCALE; if (paint->alignment == PANGO_ALIGN_CENTER) x -= rect.width / 2.f; else if (paint->alignment == PANGO_ALIGN_RIGHT) diff --git a/src/api-impl-jni/text/android_text_Layout.c b/src/api-impl-jni/text/android_text_Layout.c index ce9270e5..d8be648a 100644 --- a/src/api-impl-jni/text/android_text_Layout.c +++ b/src/api-impl-jni/text/android_text_Layout.c @@ -2,6 +2,7 @@ #include #include "../defines.h" +#include "../util.h" #include "../graphics/AndroidPaint.h" #include "../generated_headers/android_text_Layout.h" @@ -149,3 +150,22 @@ JNIEXPORT void JNICALL Java_android_text_Layout_native_1draw(JNIEnv *env, jobjec gtk_snapshot_append_layout(snapshot, pango_layout, &android_paint->color); } + +JNIEXPORT void JNICALL Java_android_text_Layout_native_1draw_1custom_1canvas(JNIEnv *env, jobject object, jlong layout, jobject canvas, jobject paint) +{ + PangoLayout *pango_layout = PANGO_LAYOUT(_PTR(layout)); + + const gchar *text = pango_layout_get_text(pango_layout); + PangoLayoutIter *pango_iter = pango_layout_get_iter(pango_layout); + do { + PangoLayoutLine *pango_line = pango_layout_iter_get_line_readonly(pango_iter); + + jstring text_jstr = (*env)->NewStringUTF(env, text + pango_line->start_index); + jint end = (*env)->GetStringLength(env, text_jstr); + if (pango_line->length < end) + end = pango_line->length; + jfloat y = (float)pango_layout_iter_get_baseline(pango_iter) / PANGO_SCALE; + (*env)->CallVoidMethod(env, canvas, handle_cache.canvas.drawText, text_jstr, (jint)0, end, (jfloat)0, y, paint); + (*env)->DeleteLocalRef(env, text_jstr); + } while (pango_layout_iter_next_line(pango_iter)); +} diff --git a/src/api-impl-jni/util.c b/src/api-impl-jni/util.c index e60f035d..80f078ca 100644 --- a/src/api-impl-jni/util.c +++ b/src/api-impl-jni/util.c @@ -175,6 +175,9 @@ void set_up_handle_cache(JNIEnv *env) handle_cache.webview.class = _REF((*env)->FindClass(env, "android/webkit/WebView")); handle_cache.webview.internalGetAssetManager = _METHOD(handle_cache.webview.class, "internalGetAssetManager", "()Landroid/content/res/AssetManager;"); handle_cache.webview.internalLoadChanged = _METHOD(handle_cache.webview.class, "internalLoadChanged", "(ILjava/lang/String;)V"); + + handle_cache.canvas.class = _REF((*env)->FindClass(env, "android/graphics/Canvas")); + handle_cache.canvas.drawText = _METHOD(handle_cache.canvas.class, "drawText", "(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V"); } void extract_from_apk(const char *path, const char *target) { diff --git a/src/api-impl-jni/util.h b/src/api-impl-jni/util.h index 5ede5d79..98224a91 100644 --- a/src/api-impl-jni/util.h +++ b/src/api-impl-jni/util.h @@ -128,6 +128,10 @@ struct handle_cache { jmethodID onCreate; jmethodID start; } instrumentation; + struct { + jclass class; + jmethodID drawText; + } canvas; }; extern struct handle_cache handle_cache; diff --git a/src/api-impl/android/graphics/GskCanvas.java b/src/api-impl/android/graphics/GskCanvas.java index 0b6b5619..b32d7f85 100644 --- a/src/api-impl/android/graphics/GskCanvas.java +++ b/src/api-impl/android/graphics/GskCanvas.java @@ -136,6 +136,11 @@ public class GskCanvas extends Canvas { native_concat(snapshot, matrix.native_instance); } + @Override + public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { + drawText(text.toString().substring(start, end), x, y, paint); + } + protected native void native_drawBitmap(long snapshot, long texture, int x, int y, int width, int height, long paint); protected native void native_drawRect(long snapshot, float left, float top, float right, float bottom, long paint); protected native void native_drawPath(long snapshot, long path, long paint); diff --git a/src/api-impl/android/text/Layout.java b/src/api-impl/android/text/Layout.java index 5ce2949d..2ea11fee 100644 --- a/src/api-impl/android/text/Layout.java +++ b/src/api-impl/android/text/Layout.java @@ -2,6 +2,7 @@ package android.text; import android.graphics.Canvas; import android.graphics.GskCanvas; +import android.graphics.Paint; import android.graphics.Path; public class Layout { @@ -59,8 +60,6 @@ public class Layout { } public int getHeight() { - System.out.println("height = " + native_get_height(layout)); - System.out.println("should be " + ((int)(paint.measureText("_") * 3))); return native_get_height(layout); } @@ -68,7 +67,7 @@ public class Layout { if (canvas instanceof GskCanvas) native_draw(layout, ((GskCanvas)canvas).snapshot, paint.paint); else - canvas.drawText(text.toString(), 0, 0, paint); + native_draw_custom_canvas(layout, canvas, paint); } public int getParagraphDirection(int line) { @@ -251,4 +250,5 @@ public class Layout { protected native void native_set_ellipsize(long layout, int ellipsize_mode, float ellipsize_width); protected native int native_get_ellipsis_count(long layout, int line); protected native void native_draw(long layout, long snapshot, long paint); + protected native void native_draw_custom_canvas(long layout, Canvas canvas, Paint paint); }