Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 854363e3 authored by Raph Levien's avatar Raph Levien
Browse files

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
parent 07bfc4ba
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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);

+22 −8
Original line number Diff line number Diff line
@@ -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}
+5 −4
Original line number Diff line number Diff line
@@ -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);