diff options
author | Romain Guy <romainguy@google.com> | 2012-02-24 18:01:22 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-02-24 18:01:22 -0800 |
commit | 778f67f7c0df6db42958ae58ee622070313a5a4d (patch) | |
tree | cf113821edc9061da1ba8727701f9f44b8f3cead | |
parent | b73644a94f090f551e24e2e658756a7ff127dbb2 (diff) | |
parent | 325740fb444af8fc7fb0119b2e30ce322c2ae134 (diff) | |
download | frameworks_base-778f67f7c0df6db42958ae58ee622070313a5a4d.zip frameworks_base-778f67f7c0df6db42958ae58ee622070313a5a4d.tar.gz frameworks_base-778f67f7c0df6db42958ae58ee622070313a5a4d.tar.bz2 |
Merge "Add hooks to implement Canvas.drawTextOnPath() in GL"
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 28 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayout.cpp | 5 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 36 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 40 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 6 | ||||
-rw-r--r-- | tests/HwAccelerationTest/AndroidManifest.xml | 9 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java | 84 |
9 files changed, 206 insertions, 10 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index f5fc708..36582af 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -1208,14 +1208,38 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) { - // TODO: Implement + if (index < 0 || index + count > text.length) { + throw new ArrayIndexOutOfBoundsException(); + } + + int modifiers = setupModifiers(paint); + try { + nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset, + paint.mBidiFlags, paint.mNativePaint); + } finally { + if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); + } } + private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count, + int path, float hOffset, float vOffset, int bidiFlags, int nativePaint); + @Override public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { - // TODO: Implement + if (text.length() == 0) return; + + int modifiers = setupModifiers(paint); + try { + nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset, + paint.mBidiFlags, paint.mNativePaint); + } finally { + if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers); + } } + private static native void nDrawTextOnPath(int renderer, String text, int start, int end, + int path, float hOffset, float vOffset, int bidiFlags, int nativePaint); + @Override public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int dir, Paint paint) { diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp index 2241f60..2beedad 100644 --- a/core/jni/android/graphics/TextLayout.cpp +++ b/core/jni/android/graphics/TextLayout.cpp @@ -101,11 +101,6 @@ void TextLayout::drawTextOnPath(SkPaint* paint, const jchar* text, int count, SkScalar h_ = SkFloatToScalar(hOffset); SkScalar v_ = SkFloatToScalar(vOffset); - if (!needsLayout(text, count, bidiFlags)) { - canvas->drawTextOnPathHV(text, count << 1, *path, h_, v_, *paint); - return; - } - sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, text, 0, count, count, bidiFlags); if (value == NULL) { diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index cdce4f9..f0560c1 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -521,6 +521,20 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); } +static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count, + SkPath* path, jfloat hOffset, jfloat vOffset, int flags, SkPaint* paint) { + sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, + text, 0, count, count, flags); + if (value == NULL) { + return; + } + const jchar* glyphs = value->getGlyphs(); + size_t glyphsCount = value->getGlyphsCount(); + int bytesCount = glyphsCount * sizeof(jchar); + renderer->drawTextOnPath((const char*) glyphs, bytesCount, glyphsCount, path, + hOffset, vOffset, paint); +} + static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, jint start, jint count, jint contextCount, jfloat x, jfloat y, int flags, SkPaint* paint) { @@ -551,6 +565,24 @@ static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz, env->ReleaseStringChars(text, textArray); } +static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz, + OpenGLRenderer* renderer, jcharArray text, jint index, jint count, + SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) { + jchar* textArray = env->GetCharArrayElements(text, NULL); + renderTextOnPath(renderer, textArray + index, count, path, + hOffset, vOffset, flags, paint); + env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); +} + +static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz, + OpenGLRenderer* renderer, jstring text, jint start, jint end, + SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) { + const jchar* textArray = env->GetStringChars(text, NULL); + renderTextOnPath(renderer, textArray + start, end - start, path, + hOffset, vOffset, flags, paint); + env->ReleaseStringChars(text, textArray); +} + static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, jcharArray text, jint index, jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags, @@ -885,6 +917,10 @@ static JNINativeMethod gMethods[] = { { "nDrawText", "(ILjava/lang/String;IIFFII)V", (void*) android_view_GLES20Canvas_drawText }, + { "nDrawTextOnPath", "(I[CIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath }, + { "nDrawTextOnPath", "(ILjava/lang/String;IIIFFII)V", + (void*) android_view_GLES20Canvas_drawTextOnPath }, + { "nDrawTextRun", "(I[CIIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextRunArray }, { "nDrawTextRun", "(ILjava/lang/String;IIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextRun }, diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index f9088ac..8153823 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -61,6 +61,7 @@ const char* DisplayList::OP_NAMES[] = { "DrawLines", "DrawPoints", "DrawText", + "DrawTextOnPath", "DrawPosText", "ResetShader", "SetupShader", @@ -483,7 +484,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { break; case DrawText: { getText(&text); - int count = getInt(); + int32_t count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(renderer); @@ -492,6 +493,17 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { text.text(), text.length(), count, x, y, paint, length); } break; + case DrawTextOnPath: { + getText(&text); + int32_t count = getInt(); + SkPath* path = getPath(); + float hOffset = getFloat(); + float vOffset = getFloat(); + SkPaint* paint = getPaint(renderer); + ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], + text.text(), text.length(), count, paint); + } + break; case DrawPosText: { getText(&text); int count = getInt(); @@ -890,6 +902,19 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u renderer.drawText(text.text(), text.length(), count, x, y, paint, length); } break; + case DrawTextOnPath: { + getText(&text); + int32_t count = getInt(); + SkPath* path = getPath(); + float hOffset = getFloat(); + float vOffset = getFloat(); + SkPaint* paint = getPaint(renderer); + DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], + text.text(), text.length(), count, paint); + renderer.drawTextOnPath(text.text(), text.length(), count, path, + hOffset, vOffset, paint); + } + break; case DrawPosText: { getText(&text); int32_t count = getInt(); @@ -1331,6 +1356,19 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, addSkip(location); } +void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, + SkPath* path, float hOffset, float vOffset, SkPaint* paint) { + if (!text || count <= 0) return; + addOp(DisplayList::DrawTextOnPath); + addText(text, bytesCount); + addInt(count); + addPath(path); + addFloat(hOffset); + addFloat(vOffset); + paint->setAntiAlias(true); + addPaint(paint); +} + void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { if (!text || count <= 0) return; diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 4a299c6..5d1b460 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -99,6 +99,7 @@ public: DrawLines, DrawPoints, DrawText, + DrawTextOnPath, DrawPosText, ResetShader, SetupShader, @@ -310,6 +311,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 drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + float hOffset, float vOffset, SkPaint* paint); virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 55e2ca5..6f0f836 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -2292,6 +2292,11 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, drawTextDecorations(text, bytesCount, length, oldX, oldY, paint); } +void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + float hOffset, float vOffset, SkPaint* paint) { + // TODO: Implement +} + void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { if (mSnapshot->isIgnored()) return; diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 3f63c3fe..4d7a491 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -124,8 +124,10 @@ 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 drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + float hOffset, float vOffset, SkPaint* paint); + 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/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index ed78daa3..b310d93 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -568,6 +568,15 @@ </activity> <activity + android:name="TextOnPathActivity" + android:label="_TextOnPath"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="PathsCacheActivity" android:label="_PathsCache"> <intent-filter> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java new file mode 100644 index 0000000..439d029 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.os.Bundle; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class TextOnPathActivity extends Activity { + private Path mPath; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mPath = makePath(); + + final TextOnPathView view = new TextOnPathView(this); + setContentView(view); + } + + private Path makePath() { + Path path = new Path(); + buildPath(path); + return path; + } + + private void buildPath(Path path) { + path.moveTo(0.0f, 0.0f); + path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f); + path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f); + path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f); + } + + public class TextOnPathView extends View { + private static final String TEST_STRING = "Hello OpenGL renderer, text on path! "; + + private final Paint mPaint; + private final String mText; + + public TextOnPathView(Context c) { + super(c); + + mPaint = new Paint(); + mPaint.setAntiAlias(true); + mPaint.setColor(0xff000000); + + StringBuilder builder = new StringBuilder(TEST_STRING.length() * 5); + for (int i = 0; i < 5; i++) { + builder.append(TEST_STRING); + } + mText = builder.toString(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.drawARGB(255, 255, 255, 255); + + canvas.translate(550.0f, 60.0f); + canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint); + } + } +} |