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

Commit 3f0d6167 authored by Raph Levien's avatar Raph Levien
Browse files

Simple implementation of drawPosText

The existing implementation of drawPosText is broken in various subtle
ways, in any case doesn't work with Minikin. This patch just implements
it by drawing a separate run for each Unicode character, which should
have the least surprising results for complex scripts such as Khmer.

Part of b/11750374 Resolve TODO items for Minikin

Change-Id: I874ae3c163f0cbe3cdf0160564fab04305aed5aa
parent 45b161d2
Loading
Loading
Loading
Loading
+1 −25
Original line number Diff line number Diff line
@@ -853,31 +853,7 @@ class GLES20Canvas extends HardwareCanvas {
    private static native void nDrawPoints(long renderer, float[] points,
            int offset, int count, long paint);

    @SuppressWarnings("deprecation")
    @Override
    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
        if (index < 0 || index + count > text.length || count * 2 > pos.length) {
            throw new IndexOutOfBoundsException();
        }

        nDrawPosText(mRenderer, text, index, count, pos, paint.mNativePaint);
    }

    private static native void nDrawPosText(long renderer, char[] text, int index, int count,
            float[] pos, long paint);

    @SuppressWarnings("deprecation")
    @Override
    public void drawPosText(String text, float[] pos, Paint paint) {
        if (text.length() * 2 > pos.length) {
            throw new ArrayIndexOutOfBoundsException();
        }

        nDrawPosText(mRenderer, text, 0, text.length(), pos, paint.mNativePaint);
    }

    private static native void nDrawPosText(long renderer, String text, int start, int end,
            float[] pos, long paint);
    // Note: drawPosText just uses implementation in Canvas

    @Override
    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
+0 −4
Original line number Diff line number Diff line
@@ -1320,10 +1320,6 @@ static JNINativeMethod gCanvasMethods[] = {
        (void*) SkCanvasGlue::drawTextRun___CIIIIFFZPaintTypeface},
    {"native_drawTextRun","(JLjava/lang/String;IIIIFFZJJ)V",
        (void*) SkCanvasGlue::drawTextRun__StringIIIIFFZPaintTypeface},
    {"native_drawPosText","(J[CII[FJ)V",
        (void*) SkCanvasGlue::drawPosText___CII_FPaint},
    {"native_drawPosText","(JLjava/lang/String;[FJ)V",
        (void*) SkCanvasGlue::drawPosText__String_FPaint},
    {"native_drawTextOnPath","(J[CIIJFFIJJ)V",
        (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint},
    {"native_drawTextOnPath","(JLjava/lang/String;JFFIJJ)V",
+0 −47
Original line number Diff line number Diff line
@@ -840,49 +840,6 @@ static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
    env->ReleaseStringChars(text, textArray);
}

static void renderPosText(OpenGLRenderer* renderer, const jchar* text, int count,
        const jfloat* positions, jint bidiFlags, SkPaint* paint) {
    sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
            text, 0, count, count, bidiFlags);
    if (value == NULL) {
        return;
    }
    const jchar* glyphs = value->getGlyphs();
    size_t glyphsCount = value->getGlyphsCount();
    if (count < int(glyphsCount)) glyphsCount = count;
    int bytesCount = glyphsCount * sizeof(jchar);

    renderer->drawPosText((const char*) glyphs, bytesCount, glyphsCount, positions, paint);
}

static void android_view_GLES20Canvas_drawPosTextArray(JNIEnv* env, jobject clazz,
        jlong rendererPtr, jcharArray text, jint index, jint count,
        jfloatArray pos, jlong paintPtr) {
    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
    jchar* textArray = env->GetCharArrayElements(text, NULL);
    jfloat* positions = env->GetFloatArrayElements(pos, NULL);
    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);

    renderPosText(renderer, textArray + index, count, positions, kBidi_LTR, paint);

    env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT);
    env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
}

static void android_view_GLES20Canvas_drawPosText(JNIEnv* env, jobject clazz,
        jlong rendererPtr, jstring text, jint start, jint end,
        jfloatArray pos, jlong paintPtr) {
    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
    const jchar* textArray = env->GetStringChars(text, NULL);
    jfloat* positions = env->GetFloatArrayElements(pos, NULL);
    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);

    renderPosText(renderer, textArray + start, end - start, positions, kBidi_LTR, paint);

    env->ReleaseFloatArrayElements(pos, positions, JNI_ABORT);
    env->ReleaseStringChars(text, textArray);
}

// ----------------------------------------------------------------------------
// Display lists
// ----------------------------------------------------------------------------
@@ -1039,10 +996,6 @@ static JNINativeMethod gMethods[] = {
    { "nDrawTextRun",       "(JLjava/lang/String;IIIIFFZJJ)V",
            (void*) android_view_GLES20Canvas_drawTextRun },

    { "nDrawPosText",       "(J[CII[FJ)V",     (void*) android_view_GLES20Canvas_drawPosTextArray },
    { "nDrawPosText",       "(JLjava/lang/String;II[FJ)V",
            (void*) android_view_GLES20Canvas_drawPosText },

    { "nGetClipBounds",     "(JLandroid/graphics/Rect;)Z",
            (void*) android_view_GLES20Canvas_getClipBounds },

+8 −15
Original line number Diff line number Diff line
@@ -1712,7 +1712,8 @@ public class Canvas {
     * the pos array.
     *
     * This method does not support glyph composition and decomposition and
     * should therefore not be used to render complex scripts.
     * should therefore not be used to render complex scripts. It also doesn't
     * handle supplementary characters (eg emoji).
     *
     * @param text     The text to be drawn
     * @param index    The index of the first character to draw
@@ -1727,8 +1728,9 @@ public class Canvas {
        if (index < 0 || index + count > text.length || count*2 > pos.length) {
            throw new IndexOutOfBoundsException();
        }
        native_drawPosText(mNativeCanvasWrapper, text, index, count, pos,
                paint.mNativePaint);
        for (int i = 0; i < count; i++) {
            drawText(text, index + i, 1, pos[i * 2], pos[i * 2 + 1], paint);
        }
    }

    /**
@@ -1736,7 +1738,8 @@ public class Canvas {
     * the pos array.
     *
     * This method does not support glyph composition and decomposition and
     * should therefore not be used to render complex scripts.
     * should therefore not be used to render complex scripts. It also doesn't
     * handle supplementary characters (eg emoji).
     *
     * @param text  The text to be drawn
     * @param pos   Array of [x,y] positions, used to position each character
@@ -1744,10 +1747,7 @@ public class Canvas {
     */
    @Deprecated
    public void drawPosText(@NonNull String text, @NonNull float[] pos, @NonNull Paint paint) {
        if (text.length()*2 > pos.length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        native_drawPosText(mNativeCanvasWrapper, text, pos, paint.mNativePaint);
        drawPosText(text.toCharArray(), 0, text.length(), pos, paint);
    }

    /**
@@ -2009,13 +2009,6 @@ public class Canvas {
            int start, int count, int contextStart, int contextCount,
            float x, float y, boolean isRtl, long nativePaint, long nativeTypeface);

    private static native void native_drawPosText(long nativeCanvas,
                                                  char[] text, int index,
                                                  int count, float[] pos,
                                                  long nativePaint);
    private static native void native_drawPosText(long nativeCanvas,
                                                  String text, float[] pos,
                                                  long nativePaint);
    private static native void native_drawTextOnPath(long nativeCanvas,
                                                     char[] text, int index,
                                                     int count, long nativePath,