OSDN Git Service

Fix incorrect getStringBounds (Minikin)
authorRaph Levien <raph@google.com>
Wed, 4 Jun 2014 02:56:05 +0000 (19:56 -0700)
committerRaph Levien <raph@google.com>
Wed, 4 Jun 2014 04:11:06 +0000 (21:11 -0700)
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
core/jni/android/graphics/MinikinUtils.h
core/jni/android/graphics/Paint.cpp
graphics/java/android/graphics/Paint.java

index 597160b..a88b747 100644 (file)
@@ -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);
index f85074c..997d6e3 100644 (file)
@@ -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);
 
index 4642cfd..4000b07 100644 (file)
@@ -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<TextLayoutValue> 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<SkPaint*>(paintHandle);;
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(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<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(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<jchar*>(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}
index f97add8..4268a24 100644 (file)
@@ -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);