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

Commit fb9ffe02 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "First pass at implementing Canvas.drawPosText() in GL"

parents 1be4afec eb9a5367
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