From 854363e3d2fb2a9e41d8719f4a2f0f8b89440a46 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Tue, 3 Jun 2014 19:56:05 -0700 Subject: [PATCH] Fix incorrect getStringBounds (Minikin) This patch wires up getStringBounds to do the layout with Minikin to get accurate bounds, and with the correct typeface. It fixes bug 15416575 "getStringBounds gives wrong result in Minikin". Change-Id: I5c020bc372acb1d785a33c3c296239c151bd8c87 --- core/jni/android/graphics/MinikinUtils.cpp | 2 +- core/jni/android/graphics/MinikinUtils.h | 2 +- core/jni/android/graphics/Paint.cpp | 30 ++++++++++++++++------ graphics/java/android/graphics/Paint.java | 9 ++++--- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp index 597160b22767b..a88b747772e55 100644 --- a/core/jni/android/graphics/MinikinUtils.cpp +++ b/core/jni/android/graphics/MinikinUtils.cpp @@ -23,7 +23,7 @@ namespace android { -void MinikinUtils::SetLayoutProperties(Layout* layout, SkPaint* paint, int flags, +void MinikinUtils::SetLayoutProperties(Layout* layout, const SkPaint* paint, int flags, TypefaceImpl* typeface) { TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface); layout->setFontCollection(resolvedFace->fFontCollection); diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h index f85074cd572c3..997d6e30b35e1 100644 --- a/core/jni/android/graphics/MinikinUtils.h +++ b/core/jni/android/graphics/MinikinUtils.h @@ -28,7 +28,7 @@ namespace android { class MinikinUtils { public: - static void SetLayoutProperties(Layout* layout, SkPaint* paint, int flags, + static void SetLayoutProperties(Layout* layout, const SkPaint* paint, int flags, TypefaceImpl* face); static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout); diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 4642cfd0b4148..4000b077519be 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -985,34 +985,48 @@ public: return count; } - static void doTextBounds(JNIEnv* env, const jchar* text, int count, - jobject bounds, const SkPaint& paint, jint bidiFlags) { + static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds, + const SkPaint& paint, TypefaceImpl* typeface, jint bidiFlags) { SkRect r; SkIRect ir; +#ifdef USE_MINIKIN + Layout layout; + MinikinUtils::SetLayoutProperties(&layout, &paint, bidiFlags, typeface); + layout.doLayout(text, count); + MinikinRect rect; + layout.getBounds(&rect); + r.fLeft = rect.mLeft; + r.fTop = rect.mTop; + r.fRight = rect.mRight; + r.fBottom = rect.mBottom; +#else sp value = TextLayoutEngine::getInstance().getValue(&paint, text, 0, count, count, bidiFlags); if (value == NULL) { return; } paint.measureText(value->getGlyphs(), value->getGlyphsCount() << 1, &r); +#endif r.roundOut(&ir); GraphicsJNI::irect_to_jrect(ir, env, bounds); } - static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle, + static void getStringBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle, jstring text, jint start, jint end, jint bidiFlags, jobject bounds) { const SkPaint* paint = reinterpret_cast(paintHandle);; + TypefaceImpl* typeface = reinterpret_cast(typefaceHandle); const jchar* textArray = env->GetStringChars(text, NULL); - doTextBounds(env, textArray + start, end - start, bounds, *paint, bidiFlags); + doTextBounds(env, textArray + start, end - start, bounds, *paint, typeface, bidiFlags); env->ReleaseStringChars(text, textArray); } - static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle, + static void getCharArrayBounds(JNIEnv* env, jobject, jlong paintHandle, jlong typefaceHandle, jcharArray text, jint index, jint count, jint bidiFlags, jobject bounds) { const SkPaint* paint = reinterpret_cast(paintHandle); + TypefaceImpl* typeface = reinterpret_cast(typefaceHandle); const jchar* textArray = env->GetCharArrayElements(text, NULL); - doTextBounds(env, textArray + index, count, bounds, *paint, bidiFlags); + doTextBounds(env, textArray + index, count, bounds, *paint, typeface, bidiFlags); env->ReleaseCharArrayElements(text, const_cast(textArray), JNI_ABORT); } @@ -1094,9 +1108,9 @@ static JNINativeMethod methods[] = { (void*) SkPaintGlue::getTextRunCursor__String}, {"native_getTextPath","(JJI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C}, {"native_getTextPath","(JJILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String}, - {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V", + {"nativeGetStringBounds", "(JJLjava/lang/String;IIILandroid/graphics/Rect;)V", (void*) SkPaintGlue::getStringBounds }, - {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V", + {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", (void*) SkPaintGlue::getCharArrayBounds }, {"native_setShadowLayer", "(JFFFI)V", (void*)SkPaintGlue::setShadowLayer}, {"native_hasShadowLayer", "(J)Z", (void*)SkPaintGlue::hasShadowLayer} diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index f97add88458ce..4268a244fd2aa 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -2174,7 +2174,7 @@ public class Paint { if (bounds == null) { throw new NullPointerException("need bounds Rect"); } - nativeGetStringBounds(mNativePaint, text, start, end, mBidiFlags, bounds); + nativeGetStringBounds(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, bounds); } /** @@ -2194,7 +2194,8 @@ public class Paint { if (bounds == null) { throw new NullPointerException("need bounds Rect"); } - nativeGetCharArrayBounds(mNativePaint, text, index, count, mBidiFlags, bounds); + nativeGetCharArrayBounds(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, + bounds); } @Override @@ -2265,9 +2266,9 @@ public class Paint { int bidiFlags, char[] text, int index, int count, float x, float y, long path); private static native void native_getTextPath(long native_object, long native_typeface, int bidiFlags, String text, int start, int end, float x, float y, long path); - private static native void nativeGetStringBounds(long nativePaint, + private static native void nativeGetStringBounds(long nativePaint, long native_typeface, String text, int start, int end, int bidiFlags, Rect bounds); - private static native void nativeGetCharArrayBounds(long nativePaint, + private static native void nativeGetCharArrayBounds(long nativePaint, long native_typeface, char[] text, int index, int count, int bidiFlags, Rect bounds); private static native void finalizer(long nativePaint);