diff options
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 28 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 52 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 32 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 14 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 2 |
6 files changed, 128 insertions, 3 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 700d3df..761a788 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -945,14 +945,38 @@ 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) { int modifiers = setupModifiers(paint); diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index c8251bf..3bf28eb 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -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 }, diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 656a384..824ab4f 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -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); } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 5d922db..dd7ec4f 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -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); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 12ed205..6ec87f3 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -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()); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 019e9b2..a9cda47 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -124,6 +124,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); |