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

Commit eb9a5367 authored by Romain Guy's avatar Romain Guy
Browse files

First pass at implementing Canvas.drawPosText() in GL

Change-Id: Ia3ac347e95d57eb86c63045156c8dbc0572b03cb
parent d1d4bb70
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -945,13 +945,37 @@ class GLES20Canvas extends HardwareCanvas {

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

        int modifiers = setupModifiers(paint);
        try {
            nDrawPosText(mRenderer, text, index, count, pos, paint.mNativePaint);
        } finally {
            if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
        }
    }

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

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

        int modifiers = setupModifiers(paint);
        try {
            nDrawPosText(mRenderer, text, 0, text.length(), pos, paint.mNativePaint);
        } finally {
            if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
        }
    }

    private static native void nDrawPosText(int renderer, String text, int start, int end,
            float[] pos, int paint);

    @Override
    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
+52 −0
Original line number Diff line number Diff line
@@ -567,6 +567,54 @@ 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 dirFlags, SkPaint* paint) {
    sp<TextLayoutCacheValue> value;
#if USE_TEXT_LAYOUT_CACHE
    value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, dirFlags);
    if (value == NULL) {
        ALOGE("Cannot get TextLayoutCache value for text = '%s'",
                String8(text, count).string());
        return;
    }
#else
    value = new TextLayoutCacheValue(count);
    TextLayoutEngine::getInstance().computeValues(value.get(), paint,
            text, 0, count, count, dirFlags);
#endif

    const jchar* glyphs = value->getGlyphs();
    size_t glyphsCount = value->getGlyphsCount();
    int bytesCount = glyphsCount * sizeof(jchar);

    renderer->drawPosText((const char*) glyphs, bytesCount,
            count < int(glyphsCount) ? count : glyphsCount, positions, paint);
}

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

    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,
        OpenGLRenderer* renderer, jstring text, jint start, jint end,
        jfloatArray pos, SkPaint* paint) {
    const jchar* textArray = env->GetStringChars(text, NULL);
    jfloat* positions = env->GetFloatArrayElements(pos, NULL);

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

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

// ----------------------------------------------------------------------------
// Display lists
// ----------------------------------------------------------------------------
@@ -830,6 +878,10 @@ static JNINativeMethod gMethods[] = {
    { "nDrawTextRun",       "(ILjava/lang/String;IIIIFFII)V",
            (void*) android_view_GLES20Canvas_drawTextRun },

    { "nDrawPosText",       "(I[CII[FI)V",     (void*) android_view_GLES20Canvas_drawPosTextArray },
    { "nDrawPosText",       "(ILjava/lang/String;II[FI)V",
            (void*) android_view_GLES20Canvas_drawPosText },

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

+32 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ const char* DisplayList::OP_NAMES[] = {
    "DrawLines",
    "DrawPoints",
    "DrawText",
    "DrawPosText",
    "ResetShader",
    "SetupShader",
    "ResetColorFilter",
@@ -482,6 +483,15 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
                    text.text(), text.length(), count, x, y, paint, length);
            }
            break;
            case DrawPosText: {
                getText(&text);
                int count = getInt();
                int positionsCount = 0;
                float* positions = getFloats(positionsCount);
                SkPaint* paint = getPaint();
                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
                    text.text(), text.length(), count, paint);
            }
            case ResetShader: {
                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
            }
@@ -844,6 +854,17 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
                renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
            }
            break;
            case DrawPosText: {
                getText(&text);
                int count = getInt();
                int positionsCount = 0;
                float* positions = getFloats(positionsCount);
                SkPaint* paint = getPaint();
                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
                        OP_NAMES[op], text.text(), text.length(), count, paint);
                renderer.drawPosText(text.text(), text.length(), count, positions, paint);
            }
            break;
            case ResetShader: {
                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
                renderer.resetShader();
@@ -1216,6 +1237,17 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
    addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length);
}

void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
        const float* positions, SkPaint* paint) {
    if (count <= 0) return;
    addOp(DisplayList::DrawPosText);
    addText(text, bytesCount);
    addInt(count);
    addFloats(positions, count * 2);
    paint->setAntiAlias(true);
    addPaint(paint);
}

void DisplayListRenderer::resetShader() {
    addOp(DisplayList::ResetShader);
}
+3 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ public:
        DrawLines,
        DrawPoints,
        DrawText,
        DrawPosText,
        ResetShader,
        SetupShader,
        ResetColorFilter,
@@ -291,6 +292,8 @@ public:
    virtual void drawPoints(float* points, int count, SkPaint* paint);
    virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
            SkPaint* paint, float length = 1.0f);
    virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
            SkPaint* paint);

    virtual void resetShader();
    virtual void setupShader(SkiaShader* shader);
+13 −1
Original line number Diff line number Diff line
@@ -2082,6 +2082,17 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
    }
}

void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
        const float* positions, SkPaint* paint) {
    if (text == NULL || count == 0) {
        return;
    }
    if (mSnapshot->isIgnored()) return;

    // TODO: implement properly
    drawText(text, bytesCount, count, 0, 0, paint);
}

void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
        float x, float y, SkPaint* paint, float length) {
    if (text == NULL || count == 0) {
@@ -2120,10 +2131,11 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
        y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
    }

    FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
#if DEBUG_GLYPHS
    ALOGD("OpenGLRenderer drawText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface()));
#endif

    FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
    fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
            paint->getTextSize());

Loading